Compare commits

...

10 Commits

Author SHA1 Message Date
ThePendulum
59424af388 Only using websockets. 2023-11-21 01:03:25 +01:00
ThePendulum
39a27f501e Refactored for SocketIO server. 2023-11-13 22:56:46 +01:00
ThePendulum
ffdfefa6d4 1.26.12 2023-08-21 23:12:06 +02:00
ThePendulum
b3ab3bf1ba Fixed kill announce for IRC.. 2023-08-21 23:12:02 +02:00
ThePendulum
2e54d38383 1.26.11 2023-08-17 22:38:45 +02:00
ThePendulum
98a1aa8fff Revealing who used kill command in all active rooms. 2023-08-17 22:38:43 +02:00
ThePendulum
6f2a5e03e9 1.26.10 2023-07-18 23:35:55 +02:00
ThePendulum
9966c79a26 Added milliseconds to Duck result. 2023-07-18 23:35:53 +02:00
ThePendulum
a46ffb431b 1.26.9 2023-07-11 16:41:40 +02:00
ThePendulum
b9be447dba Upgraded Clive to new room user ID data. 2023-07-11 16:41:38 +02:00
6 changed files with 295 additions and 33 deletions

View File

@@ -15,7 +15,7 @@ module.exports = {
operators: ['admin'],
server: 'irc.libera.chat',
port: 6697,
socket: 'ws://127.0.0.1:3000/socket',
socket: 'ws://127.0.0.1:3000/socket/',
api: 'http://127.0.0.1:3000/api',
reconnectDelay: 10, // seconds
prefix: '~',

231
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "schat2-clive",
"version": "1.26.8",
"version": "1.26.12",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "schat2-clive",
"version": "1.26.8",
"version": "1.26.12",
"license": "ISC",
"dependencies": {
"better-sqlite3": "^8.3.0",
@@ -25,6 +25,7 @@
"markov-strings": "^3.0.1",
"mathjs": "^11.8.0",
"simple-node-logger": "^21.8.12",
"socket.io-client": "^4.7.2",
"string-similarity": "^4.0.4",
"tensify": "^0.0.4",
"vm2": "^3.9.11",
@@ -566,6 +567,11 @@
"node": ">=6.9.0"
}
},
"node_modules/@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"node_modules/@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -1337,6 +1343,47 @@
"once": "^1.4.0"
}
},
"node_modules/engine.io-client": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
}
},
"node_modules/engine.io-client/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/engine.io-client/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/engine.io-parser": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
"integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ==",
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/errors": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/errors/-/errors-0.2.0.tgz",
@@ -3742,6 +3789,74 @@
"node": ">=4"
}
},
"node_modules/socket.io-client": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
"integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-client/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-client/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"dependencies": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"engines": {
"node": ">=10.0.0"
}
},
"node_modules/socket.io-parser/node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"dependencies": {
"ms": "2.1.2"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/socket.io-parser/node_modules/ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -4432,9 +4547,9 @@
}
},
"node_modules/ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"engines": {
"node": ">=10.0.0"
},
@@ -4464,6 +4579,14 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"node_modules/xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/xtend": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",
@@ -4919,6 +5042,11 @@
"to-fast-properties": "^2.0.0"
}
},
"@socket.io/component-emitter": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
},
"@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
@@ -5504,6 +5632,38 @@
"once": "^1.4.0"
}
},
"engine.io-client": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.3.tgz",
"integrity": "sha512-9Z0qLB0NIisTRt1DZ/8U2k12RJn8yls/nXMZLn+/N8hANT3TcYjKFKcwbw5zFQiN4NTde3TSY9zb79e1ij6j9Q==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1",
"engine.io-parser": "~5.2.1",
"ws": "~8.11.0",
"xmlhttprequest-ssl": "~2.0.0"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"engine.io-parser": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.1.tgz",
"integrity": "sha512-9JktcM3u18nU9N2Lz3bWeBgxVgOKpw7yhRaoxQA3FUDZzzw+9WlA6p4G4u0RixNkg14fH7EfEc/RhpurtiROTQ=="
},
"errors": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/errors/-/errors-0.2.0.tgz",
@@ -7278,6 +7438,56 @@
}
}
},
"socket.io-client": {
"version": "4.7.2",
"resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.2.tgz",
"integrity": "sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.2",
"engine.io-client": "~6.5.2",
"socket.io-parser": "~4.2.4"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"socket.io-parser": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz",
"integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==",
"requires": {
"@socket.io/component-emitter": "~3.1.0",
"debug": "~4.3.1"
},
"dependencies": {
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
"requires": {
"ms": "2.1.2"
}
},
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}
}
},
"source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
@@ -7835,9 +8045,9 @@
}
},
"ws": {
"version": "8.2.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
"integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==",
"version": "8.11.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz",
"integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==",
"requires": {}
},
"xml-name-validator": {
@@ -7850,6 +8060,11 @@
"resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
"integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
},
"xmlhttprequest-ssl": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz",
"integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A=="
},
"xtend": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz",

View File

@@ -1,6 +1,6 @@
{
"name": "schat2-clive",
"version": "1.26.8",
"version": "1.26.12",
"description": "Game host for SChat 2-powered chat sites",
"main": "src/app.js",
"scripts": {
@@ -34,6 +34,7 @@
"markov-strings": "^3.0.1",
"mathjs": "^11.8.0",
"simple-node-logger": "^21.8.12",
"socket.io-client": "^4.7.2",
"string-similarity": "^4.0.4",
"tensify": "^0.0.4",
"vm2": "^3.9.11",

View File

@@ -59,12 +59,12 @@ function onCommand(args, context) {
const hit = Math.random() > config.duck.missRatio;
const time = new Date().getTime() - duck.getTime();
const distance = time < 600 * 1000 // show exact time up to ten minutes
const distance = time < 60 * 1000 // show digits up to one minute
? `${(time / 1000).toFixed(3)} seconds`
: Object.entries(intervalToDuration({ start: duck, end: new Date() }))
: `${Object.entries(intervalToDuration({ start: duck, end: new Date() }))
.filter(([, value]) => value > 0)
.map(([key, value]) => `${value} ${key}`)
.join(', ');
.join(', ')} and ${time % 1000} milliseconds`;
if (['bang', 'shoot'].includes(context.command)) {
if (hit) {
@@ -81,6 +81,7 @@ function onCommand(args, context) {
`That's a miss! Better luck next time, ${context.user.prefixedUsername}.`,
`The duck outsmarted you, ${context.user.prefixedUsername}`,
`Channeling Gareth Southgate, ${context.user.prefixedUsername}? You missed!`,
`Oh, and that's a bad miss, ${context.user.prefixedUsername}.`,
]);
shots.set(context.user.id, new Date());

View File

@@ -2,16 +2,28 @@
const config = require('config');
const style = require('../utils/style');
function onCommand(args, context) {
if (config.platform === 'schat') {
context.sendMessage('Shutting down... :sleeping:', context.room?.id, { type: 'message', label: false }, context.message.user?.username);
Object.keys(context.bot.rooms).forEach((roomId) => {
context.sendMessage(`Kill command used by ${style.bold(context.user.username)}, shutting down... :sleeping:`, roomId, { type: 'message', label: false });
});
if (context.message.user) {
context.sendMessage('Shutting down... :sleeping:', context.room?.id, { type: 'message', label: false }, context.message.user.username);
}
}
if (config.platform === 'irc' && context.room.id === config.user.id) {
if (config.platform === 'irc') {
context.bot.rooms.forEach((room) => {
context.sendMessage(`Kill command used by ${style.bold(context.user.username)}, shutting down... 😴`, room.id, { type: 'message', label: false });
});
if (context.room.id === config.user.id) {
// if the room ID is the bot's own nickname, it's a PM and we should reply to the sender
context.sendMessage('Shutting down... 😴', context.user.id, { label: false });
} else if (config.platform === 'irc') {
context.sendMessage('Shutting down... 😴', context.room?.id, { type: 'message', label: false });
context.sendMessage('Shutting down... 😴', context.user.id, { type: 'message', label: false }, context.message.user.username);
}
}
context.logger.info(`Kill command used by ${context.user.username}`);

View File

@@ -3,7 +3,8 @@
const config = require('config');
const { setTimeout: delay } = require('timers/promises');
const bhttp = require('bhttp');
const WebSocket = require('ws');
// const WebSocket = require('ws');
const io = require('socket.io-client');
const logger = require('simple-node-logger').createSimpleLogger();
const { argv } = require('yargs');
@@ -60,8 +61,27 @@ async function onRooms({ rooms }, bot) {
const usersRes = await bhttp.get(`${config.api}/room/${rooms.map((room) => room.id).join(',')}/users`);
const users = usersRes.body;
const userIdsByRoom = Object.values(users).reduce((acc, user) => {
user.sharedRooms.forEach((roomId) => {
if (!acc[roomId]) {
acc[roomId] = [];
}
acc[roomId].push(user.id);
});
return acc;
}, {});
/* eslint-disable no-param-reassign */
bot.rooms = rooms.reduce((acc, room) => ({ ...acc, [room.id]: room }), {});
bot.rooms = rooms.reduce((acc, room) => ({
...acc,
[room.id]: {
...room,
userIds: userIdsByRoom[room.id],
},
}), {});
bot.users = { ...bot.users, ...users };
/* eslint-enable no-param-reassign */
@@ -109,7 +129,10 @@ function handleError(error, socket, domain, data) {
}
async function connect(bot, games) {
const socket = { ws: { readyState: 0 } };
const socket = {
ws: { readyState: 0 },
io: {},
};
socket.connect = async () => {
try {
@@ -121,13 +144,29 @@ async function connect(bot, games) {
logger.info(`Attempting to connect to ${config.socket}`);
socket.ws = new WebSocket(`${config.socket}?${new URLSearchParams({ v: wsCreds.wsId, t: wsCreds.timestamp }).toString()}`, [], {
headers: {
const { origin, pathname } = new URL(config.socket);
socket.io = io(origin, {
transports: ['websocket'],
path: pathname,
query: {
v: wsCreds.wsId,
t: wsCreds.timestamp,
},
extraHeaders: {
cookie: sessionCookie,
},
});
socket.ws.on('message', async (msg) => {
socket.io.on('connect', () => {
logger.info(`Connected to ${config.socket}`);
});
socket.io.on('connect_error', (error) => {
logger.info(`Failed to connect to ${config.socket}: ${error}`);
});
socket.io.on('_', async (msg) => {
const [domain, data] = JSON.parse(msg);
logger.debug(`Received ${domain}: ${JSON.stringify(data)}`);
@@ -141,18 +180,12 @@ async function connect(bot, games) {
}
});
socket.ws.on('close', async (info) => {
socket.io.on('close', async (info) => {
logger.error(`WebSocket closed, reconnecting in ${config.reconnectDelay} seconds: ${info}`);
await delay(config.reconnectDelay * 1000);
socket.connect();
});
socket.ws.on('error', async (error) => {
logger.error(`WebSocket error: ${error.message}`);
});
logger.info(`Connected to ${config.socket}`);
} catch (error) {
logger.error(`Failed to connect, retrying in ${config.reconnectDelay} seconds: ${error.message}`);
@@ -162,7 +195,7 @@ async function connect(bot, games) {
};
socket.transmit = (domain, data) => {
socket.ws.send(JSON.stringify([domain, data]));
socket.io.emit('_', JSON.stringify([domain, data]));
};
socket.connect();