modified: .gitignore

modified:   README.md
	new file:   tools/clientManager.js
	new file:   tools/configManager.js
	new file:   tools/pluginBase.js
	modified:   tools/pluginManager.js
	modified:   tools/websocketManager.js
This commit is contained in:
2024-11-23 18:00:25 -03:00
parent 27a0c6ebf1
commit dfd1744390
7 changed files with 143 additions and 20 deletions

1
.gitignore vendored
View File

@@ -132,4 +132,5 @@ dist
# other
/plugins/*
/clients/*
.vscode/*

View File

@@ -2,7 +2,7 @@
# TODOs:
## main:
- [ ] implement universal(ish) platform bridge (classes + extend?)
- [ ] DO THIS: implement universal(ish) platform bridge (classes + extend?)
- [ ] make main server + dashboard
- [ ] make it so plugins have "public" functions and variables that can be executed from dashboard with arguments
@@ -13,7 +13,7 @@
- [ ] bot command maker
- [ ] poll system
- [ ] live audio transcription / captions
- [ ] anonym questions
- [ ] anonym questions (from highlighted messages or points?)
- [ ] subathon timer
- [ ] screen effects (confetti)
- [ ] audio effect player

26
tools/clientManager.js Normal file
View File

@@ -0,0 +1,26 @@
const clc = require("cli-color");
module.exports = {
registerClient: function (req, action) {
ip = req.socket.remoteAddress;
protocol = req.headers['sec-websocket-protocol'];
switch (action) {
case "add":
console.log(clc.greenBright(`+client ${ip} with protocol: ${protocol} Connected `));
break;
case "remove":
console.log(clc.redBright(`-client ${ip} with protocol: ${protocol} Disconnected`));
break;
}
},
broadcastMessage: function (wss, msg, protocol) {
wss.clients.forEach(client => {
if (client.readyState === WebSocketServer.OPEN) {
if (client.protocol.startsWith(protocol) || protocol == "all") {
client.send(msg);
//console.log(`Sent message: ${msg} to ${client._socket.remoteAddress} with protocol: ${client.protocol}`);
}
}
});
}
}

80
tools/configManager.js Normal file
View File

@@ -0,0 +1,80 @@
const clc = require("cli-color");
const path = require('path');
const fs = require('fs');
module.exports = class configManager {
constructor(configFolder, fileName) {
this.args = process.argv.splice(2);
this.settings = this.#readConfig(configFolder, fileName);
this.platform = this.#getPlatform();
this.#loadPlatformPlugin();
}
#readConfig(configFolder, fileName) {
var fullPath = path.join(configFolder, fileName);
if (!fs.existsSync(configFolder)) {
fs.mkdirSync(configFolder);
}
if (!fs.existsSync(fullPath)) {
console.log(clc.yellowBright(`No config file found, creating ${fileName}`));
fs.writeFileSync(fullPath, JSON.stringify(
{
"default_platform": "",
"platforms": [
{
"twitch": {
"username": "",// your_twitch_handle
"Oauth": ""// get from
}
},
{
"youtube": {
"handle": ""// @your_youtube_handle
}
}
],
"client_prefix": "Client_",
"plugin_prefix": "Plugin_",
"command_prefix": "!",
"sticker_prefix": "#",
"ws_host": "localhost",
"ws_port": 8080
}
, null, 4
));
process.exit(1);
} else {
console.log(clc.greenBright(`Using ${fileName} as config file`));
return JSON.parse(fs.readFileSync(fullPath, 'utf8'));
}
}
#getPlatform() {
if (this.args.length == 0) {
if (this.settings.default_platform == "") {
console.log(clc.red("No platform was provided as an argument or set as default in config file"));
process.exit(1);
} else {
return this.settings.default_platform;
}
} else {
return this.args[0];
}
}
#loadPlatformPlugin() {
const directoryPath = path.join(__dirname, "platformSupport");
fs.readdir(directoryPath, function (err, files) {
if (err) {
return console.log('Unable to scan directory: ' + err);
}
console.log(files)
files.forEach(function (file) {
var platformLibrary = require(path.join(directoryPath, file))
//platform = new platformLibrary("");
});
});
}
}

15
tools/pluginBase.js Normal file
View File

@@ -0,0 +1,15 @@
const clc = require("cli-color");
const path = require('path');
const fs = require('fs');
module.exports = class pluginBase {
constructor({ pluginData, pluginPath = __dirname }) {
console.log(pluginData)
}
#Initialize() {
}
#sendPublicData() {
}
}

View File

@@ -9,16 +9,16 @@ module.exports = class pluginManager {
this.pluginsPath = path.join(baseDir, "plugins");
this.pluginList = [];
this.#scanPluginsFolder();
console.log(`Found ${this.pluginList.length} plugin${this.pluginList.length !== 1 ? 's' : ''}!`);
}
#scanPluginsFolder() {
let pluginsFolder = fs.readdirSync(this.pluginsPath);
console.log(`Found ${pluginsFolder.length} plugin${pluginsFolder.length !== 1 ? 's' : ''}!`);
pluginsFolder.forEach((pluginFolder) => {
let filePath = path.join(this.pluginsPath, pluginFolder, "pluginData.json");
if (fs.existsSync(filePath)) {
let pluginData = JSON.parse(fs.readFileSync(filePath, 'utf8'));
this.#checkDependencies(pluginData.dependencies);
//this.#checkDependencies(pluginData.dependencies);
//FIX THIS, needs to wait for dependencies and then ask for restart or wait for them to be installed before loading
this.#loadPlugin(path.join(this.pluginsPath, pluginFolder, pluginData.entrypoint), pluginData);
} else {
@@ -28,20 +28,18 @@ module.exports = class pluginManager {
}
#checkDependencies(dependencies) {
for (const [key, value] of Object.entries(dependencies)) {
console.log(`Checking for: ${key}@${value}`);
nypm.ensureDependencyInstalled(`${key}`).then((result) => {
dependencies.forEach(dependency => {
console.log(`Checking for: ${dependency}`);
nypm.ensureDependencyInstalled(`${dependency}`).then((result) => {
if (result) {
console.log(`${key}@${value} is already installed.`);
console.log(`${dependency} is already installed.`);
} else {
console.log(`Installing ${key}@${value}`);
nypm.addDependency(`${key}@${value}`);
nypm.installDependencies().then((result) => {
console.log(result);
});
console.log(`Installing ${dependency}`);
nypm.addDependency(`${dependency}`);
}
})
}
});
nypm.installDependencies();
}
#loadPlugin(pluginPath, pluginData) {

View File

@@ -13,19 +13,22 @@ module.exports = class webSocketManager {
let protocol = req.headers['sec-websocket-protocol'];
console.log(clc.greenBright(`+client ${ip} with protocol: ${protocol} Connected `));
ws.on("close", () => this.#onClose(ip, protocol));
ws.on("message", (message) => this.#onMessage(ip, protocol, message));
ws.onerror = (error) => {
console.log(`Error: ${error.message}`);
};
ws.on("error", (error) => this.#onError(error));
});
}
#onClose(ip, protocol) {
console.log(clc.redBright(`-client ${ip} with protocol: ${protocol} Disconnected`));
}
#onMessage(ip, protocol, message) { }
#onMessage(ip, protocol, message) {
console.log(`${protocol}: ${message}`);
}
#onError(error) {
console.log(`Error: ${error.message}`);
}
broadcastMessage(message, target = "all") {
this.wsServer.clients.forEach((client) => {