Compare commits
70 Commits
854c73cc4e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4d07db766 | ||
|
|
03c940e07c | ||
|
|
fee40dd609 | ||
|
|
5671503594 | ||
|
|
0fd511cfaf | ||
|
|
9d0aa0191f | ||
|
|
9ce8928d82 | ||
|
|
abadcf5cb5 | ||
|
|
4b18df9e2c | ||
|
|
26a8d8a172 | ||
|
|
26f3493c8f | ||
|
|
fd261ef015 | ||
|
|
91201c3527 | ||
|
|
dfb4c6afa1 | ||
|
|
3b8e70208a | ||
|
|
99b60bf02c | ||
|
|
831317b9f0 | ||
|
|
2477b10900 | ||
|
|
67c29f1d72 | ||
|
|
91ed4fb1dc | ||
|
|
8ea02d1c0b | ||
|
|
b15ac7c973 | ||
|
|
c2c90019d7 | ||
|
|
686ddc8a0f | ||
|
|
463ccc1bd5 | ||
|
|
14a2b4a1b9 | ||
|
|
0c1f6cd867 | ||
|
|
7175487d77 | ||
|
|
f0eac45955 | ||
|
|
c81dce99e2 | ||
|
|
38cb1054e0 | ||
|
|
12441c5c6d | ||
|
|
1c1b071bd7 | ||
|
|
961c5c19e2 | ||
|
|
49e52d8944 | ||
|
|
63ccfa70d3 | ||
|
|
4bb8038a1d | ||
|
|
a353b9adbb | ||
|
|
bf69e93e29 | ||
|
|
6cae18e70c | ||
|
|
e7229322e4 | ||
|
|
34aa5d17dc | ||
|
|
565fd5af37 | ||
|
|
f04154d361 | ||
|
|
383663e980 | ||
|
|
7b21d4601f | ||
|
|
d0c2fcc8eb | ||
|
|
9ba90af464 | ||
|
|
6e8681e52d | ||
|
|
8ba1ed36d8 | ||
|
|
3074e88963 | ||
|
|
737b493b23 | ||
|
|
539dbd9518 | ||
|
|
59bfdbe143 | ||
|
|
560ed401cf | ||
|
|
7b91667414 | ||
|
|
fd9b6d9d1c | ||
|
|
3aae427249 | ||
|
|
bc4c8f72d0 | ||
|
|
cc4e5e762d | ||
|
|
31cedb2e9c | ||
|
|
61a616ec6b | ||
|
|
d7b7b04f78 | ||
|
|
2c9383824e | ||
|
|
cebd316939 | ||
|
|
af19db8e17 | ||
|
|
45b9a62c64 | ||
|
|
8c3164029f | ||
|
|
bec4072837 | ||
|
|
ac82b0efd0 |
32
.gitea/workflows/DRBv3-Client_Setup_tests.yaml.disabled
Normal file
32
.gitea/workflows/DRBv3-Client_Setup_tests.yaml.disabled
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
name: DRB Build Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
drb_test_setup:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Test setup script
|
||||||
|
working-directory: "./client"
|
||||||
|
run: |
|
||||||
|
sudo useradd -m -s /bin/bash pi
|
||||||
|
sudo bash setup.sh --test
|
||||||
|
|
||||||
|
- name: Test running client node
|
||||||
|
working-directory: "./client"
|
||||||
|
run: |
|
||||||
|
bash serviceStart.sh
|
||||||
24
.gitea/workflows/DRBv3_server_build.yaml
Normal file
24
.gitea/workflows/DRBv3_server_build.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
name: DRB Server Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_ENV: production
|
||||||
|
SERVER_PORT: 3000
|
||||||
|
MONGO_URL: ${{ secrets.MONGO_URL }}
|
||||||
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
drb_server_build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Build the latest code
|
||||||
|
working-directory: './server'
|
||||||
|
run: make build
|
||||||
81
.gitea/workflows/DRBv3_tests.yaml
Normal file
81
.gitea/workflows/DRBv3_tests.yaml
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: DRB Tests
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_ENV: development
|
||||||
|
MONGO_INITDB_ROOT_USERNAME: admin
|
||||||
|
MONGO_INITDB_ROOT_PASSWORD: admin
|
||||||
|
MONGO_INITDB_DATABASE: drb
|
||||||
|
SERVER_PORT: 3000
|
||||||
|
MONGO_URL: "mongodb://mongodb:27017/drb"
|
||||||
|
DISCORD_TOKEN: ${{ secrets.DISCORD_TOKEN }}
|
||||||
|
TEST_GUILD_ID: ${{ secrets.TEST_GUILD_ID }}
|
||||||
|
TEST_CLIENT_TOKEN: ${{ secrets.TEST_CLIENT_TOKEN }}
|
||||||
|
TEST_CHANNEL_ID: ${{ secrets.TEST_CHANNEL_ID }}
|
||||||
|
TEST_SYSTEM: ${{ secrets.TEST_SYSTEM }}
|
||||||
|
EXPECTED_CLIENT_ID: ${{ secrets.TEST_CLIENT_ID }}
|
||||||
|
EXPECTED_USERNAME: ${{ secrets.EXPECTED_USERNAME }}
|
||||||
|
PDAB_PORT: ${{ vars.PDAB_PORT }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
drb_mocha_tests:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
services:
|
||||||
|
mongodb:
|
||||||
|
image: mongo:latest
|
||||||
|
ports:
|
||||||
|
- 27017:27017
|
||||||
|
options: >-
|
||||||
|
--health-cmd mongo
|
||||||
|
--health-interval 10s
|
||||||
|
--health-timeout 5s
|
||||||
|
--health-retries 5
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version: '20'
|
||||||
|
|
||||||
|
- name: Remove package-lock.json (Server)
|
||||||
|
working-directory: "./server"
|
||||||
|
run: rm package-lock.json
|
||||||
|
|
||||||
|
- name: Install Node-GYP (Server)
|
||||||
|
working-directory: "./server"
|
||||||
|
run: npm install -g node-gyp
|
||||||
|
|
||||||
|
- name: Install dependencies (Server)
|
||||||
|
working-directory: "./server"
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- name: Remove package-lock.json (Client)
|
||||||
|
working-directory: "./client"
|
||||||
|
run: rm package-lock.json
|
||||||
|
|
||||||
|
- name: Install dependencies (Client)
|
||||||
|
working-directory: "./client"
|
||||||
|
run: npm install
|
||||||
|
|
||||||
|
- run: echo "Node has finished installing dependencies"
|
||||||
|
|
||||||
|
- name: Run Server tests
|
||||||
|
working-directory: "./server"
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
- name: Run Client tests
|
||||||
|
working-directory: "./client"
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
- run: echo "Completed the DRB tests"
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
name: Client Tests
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_ENV: development
|
|
||||||
DISCORD_CLIENT_ID: ${{ vars.DISCORD_CLIENT_ID }}
|
|
||||||
TEST_CHANNEL_ID: ${{ vars.TEST_CHANNEL_ID }}
|
|
||||||
TEST_GUILD_ID: ${{ vars.TEST_GUILD_ID }}
|
|
||||||
EXPECTED_CLIENT_ID: ${{ vars.EXPECTED_CLIENT_ID }}
|
|
||||||
PDAB_PORT: ${{ vars.PDAB_PORT }}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "20"
|
|
||||||
|
|
||||||
- name: Remove package-lock.json
|
|
||||||
working-directory: "./client"
|
|
||||||
run: rm package-lock.json
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: "./client"
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- run: echo "Node has finished installing dependencies"
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
working-directory: "./client"
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
- run: echo "Completed the tests"
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
name: Run Socket Server Tests
|
|
||||||
|
|
||||||
on: [push, pull_request]
|
|
||||||
|
|
||||||
env:
|
|
||||||
NODE_ENV: development
|
|
||||||
MONGO_INITDB_ROOT_USERNAME: admin
|
|
||||||
MONGO_INITDB_ROOT_PASSWORD: admin
|
|
||||||
MONGO_INITDB_DATABASE: drb
|
|
||||||
SERVER_PORT: 6000
|
|
||||||
MONGO_URL: "mongodb://mongodb:27017/drb"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
test:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
services:
|
|
||||||
mongodb:
|
|
||||||
image: mongo:latest
|
|
||||||
ports:
|
|
||||||
- 27017:27017
|
|
||||||
options: >-
|
|
||||||
--health-cmd mongo
|
|
||||||
--health-interval 10s
|
|
||||||
--health-timeout 5s
|
|
||||||
--health-retries 5
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Setup Node.js
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: "20"
|
|
||||||
|
|
||||||
- name: Remove package-lock.json
|
|
||||||
working-directory: "./server"
|
|
||||||
run: rm package-lock.json
|
|
||||||
|
|
||||||
- name: Install Node-GYP
|
|
||||||
working-directory: "./server"
|
|
||||||
run: npm install -g node-gyp
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
working-directory: "./server"
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- run: echo "Node has finished installing dependencies"
|
|
||||||
|
|
||||||
- name: Run tests
|
|
||||||
working-directory: "./server"
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
- run: echo "Completed the tests"
|
|
||||||
@@ -2,6 +2,7 @@ import { generateUniqueID } from './modules/baseUtils.mjs';
|
|||||||
import { updateId } from './modules/updateConfig.mjs';
|
import { updateId } from './modules/updateConfig.mjs';
|
||||||
import { ClientNodeConfig } from './modules/clientObjectDefinitions.mjs';
|
import { ClientNodeConfig } from './modules/clientObjectDefinitions.mjs';
|
||||||
import { initSocketConnection } from './modules/socketClient.mjs';
|
import { initSocketConnection } from './modules/socketClient.mjs';
|
||||||
|
import { checkForUpdates } from './modules/selfUpdater.mjs'
|
||||||
|
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
@@ -9,6 +10,9 @@ dotenv.config()
|
|||||||
var localNodeConfig = new ClientNodeConfig({})
|
var localNodeConfig = new ClientNodeConfig({})
|
||||||
|
|
||||||
async function boot() {
|
async function boot() {
|
||||||
|
// Check if there have been any updates
|
||||||
|
await checkForUpdates();
|
||||||
|
|
||||||
if (localNodeConfig.node.nuid === undefined || localNodeConfig.node.nuid === '' || localNodeConfig.node.nuid === '0' || localNodeConfig.node.nuid === 0) {
|
if (localNodeConfig.node.nuid === undefined || localNodeConfig.node.nuid === '' || localNodeConfig.node.nuid === '0' || localNodeConfig.node.nuid === 0) {
|
||||||
// Run the first time boot sequence
|
// Run the first time boot sequence
|
||||||
await firstTimeBoot();
|
await firstTimeBoot();
|
||||||
|
|||||||
1
client/discordAudioBot/pdab
Submodule
1
client/discordAudioBot/pdab
Submodule
Submodule client/discordAudioBot/pdab added at fc6c114473
@@ -17,7 +17,16 @@ let pdabProcess = false;
|
|||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
export const initDiscordBotClient = (clientId, callback) => {
|
let botCallback;
|
||||||
|
|
||||||
|
export const initDiscordBotClient = (clientId, callback, runPDAB = true) => {
|
||||||
|
botCallback = callback;
|
||||||
|
|
||||||
|
if (runPDAB) launchProcess("python", [join(__dirname, "./pdab/main.py"), process.env.AUDIO_DEVICE_ID, clientId, port], false, join(__dirname, "./pdab"));
|
||||||
|
pdabProcess = true; // TODO - Make this more dynamic
|
||||||
|
}
|
||||||
|
|
||||||
|
export const startPdabSocketServer = () => {
|
||||||
const port = process.env.PDAB_PORT || 3000;
|
const port = process.env.PDAB_PORT || 3000;
|
||||||
|
|
||||||
io.on('connection', (socket) => {
|
io.on('connection', (socket) => {
|
||||||
@@ -30,25 +39,25 @@ export const initDiscordBotClient = (clientId, callback) => {
|
|||||||
// Listen for the discord client ready event
|
// Listen for the discord client ready event
|
||||||
socket.on('discord_ready', (message) => {
|
socket.on('discord_ready', (message) => {
|
||||||
console.log("Message from local client", message);
|
console.log("Message from local client", message);
|
||||||
callback();
|
botCallback();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(port, async () => {
|
server.listen(port, async () => {
|
||||||
console.log(`Server is running on port ${port}`);
|
console.log(`Server is running on port ${port}`);
|
||||||
|
|
||||||
if (process.env.NODE_ENV == "production") {
|
|
||||||
launchProcess("python", [join(__dirname, "./pdab/main.py"), process.env.AUDIO_DEVICE_ID, clientId, port], false, join(__dirname, "./pdab"));
|
|
||||||
}
|
|
||||||
pdabProcess = true; // TODO - Make this more dynamic
|
|
||||||
});
|
});
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
export const closePdabSocketServer = () => {
|
export const closePdabSocketServer = () => {
|
||||||
|
if (io.sockets && io.sockets.length > 0) {
|
||||||
|
io.sockets.forEach(socket => {
|
||||||
|
socket.destroy();
|
||||||
|
})
|
||||||
|
}
|
||||||
return io.close();
|
return io.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Function to emit a command to join a voice channel
|
// Function to emit a command to join a voice channel
|
||||||
export const connectToChannel = (channelId) => {
|
export const connectToChannel = (channelId) => {
|
||||||
return new Promise((res) => {
|
return new Promise((res) => {
|
||||||
@@ -69,6 +78,15 @@ export const leaveVoiceChannel = async (guildId) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set the presense of the discord client
|
||||||
|
export const setDiscordClientPrsense = (system) => {
|
||||||
|
return new Promise((res) => {
|
||||||
|
io.timeout(25000).emit('set_system', { system: system }, (status) => {
|
||||||
|
res();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Placeholder functions (replace with actual implementation)
|
// Placeholder functions (replace with actual implementation)
|
||||||
export const checkIfConnectedToVC = async (guildId) => {
|
export const checkIfConnectedToVC = async (guildId) => {
|
||||||
console.log("Pdab process var:", pdabProcess);
|
console.log("Pdab process var:", pdabProcess);
|
||||||
@@ -114,6 +132,7 @@ export const requestDiscordID = () => {
|
|||||||
export const requestDiscordClientClose = () => {
|
export const requestDiscordClientClose = () => {
|
||||||
return new Promise((res) => {
|
return new Promise((res) => {
|
||||||
io.timeout(25000).emit('request_client_close');
|
io.timeout(25000).emit('request_client_close');
|
||||||
|
pdabProcess = false;
|
||||||
res();
|
res();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, initDiscordBotClient, requestDiscordUsername, requestDiscordID, requestDiscordClientClose } from './pdabHandler.mjs';
|
import { connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, initDiscordBotClient, requestDiscordUsername, requestDiscordID, requestDiscordClientClose, closePdabSocketServer, setDiscordClientPrsense, startPdabSocketServer } from './pdabHandler.mjs';
|
||||||
import { openOP25, closeOP25 } from '../op25Handler/op25Handler.mjs';
|
import { openOP25, closeOP25 } from '../op25Handler/op25Handler.mjs';
|
||||||
|
|
||||||
let activeDiscordClient = undefined;
|
let activeDiscordClient = undefined;
|
||||||
@@ -8,16 +8,26 @@ let activeDiscordClient = undefined;
|
|||||||
* @param {object} joinData The object containing all the information to join the server
|
* @param {object} joinData The object containing all the information to join the server
|
||||||
*/
|
*/
|
||||||
export const joinDiscordVC = async (joinData) => {
|
export const joinDiscordVC = async (joinData) => {
|
||||||
console.log("Join requested: ", joinData)
|
console.log("Join requested: ", joinData);
|
||||||
const connection = await new Promise(async (res) => {
|
const connection = await new Promise(async (res) => {
|
||||||
// Check if a client already exists
|
// Check if a client already exists
|
||||||
|
console.log("Checking if there is a client open");
|
||||||
if (!await checkIfClientIsOpen()) {
|
if (!await checkIfClientIsOpen()) {
|
||||||
|
console.log("There is no open client, starting it now");
|
||||||
|
await startPdabSocketServer();
|
||||||
|
// Open an instance of OP25
|
||||||
|
console.log("Starting OP25")
|
||||||
|
openOP25(joinData.system);
|
||||||
|
|
||||||
// Open a new client and join the requested channel with the requested ID
|
// Open a new client and join the requested channel with the requested ID
|
||||||
initDiscordBotClient(joinData.clientID, () => {
|
initDiscordBotClient(joinData.clientID, () => {
|
||||||
// Open an instance of OP25
|
console.log("Started PDAB");
|
||||||
// TODO DELTE comment DEV ONLY openOP25(joinData.system);
|
|
||||||
|
console.log("Setting the presense of the bot");
|
||||||
|
setDiscordClientPrsense(joinData.system);
|
||||||
|
|
||||||
// Add the client object to the IO instance
|
// Add the client object to the IO instance
|
||||||
|
console.log("Connecting to channel")
|
||||||
connectToChannel(joinData.channelID, (connectionStatus) => {
|
connectToChannel(joinData.channelID, (connectionStatus) => {
|
||||||
console.log("Bot Connected to VC:", connectionStatus);
|
console.log("Bot Connected to VC:", connectionStatus);
|
||||||
res(connectionStatus);
|
res(connectionStatus);
|
||||||
@@ -25,7 +35,9 @@ export const joinDiscordVC = async (joinData) => {
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Join the requested channel with the requested ID
|
// Join the requested channel with the requested ID
|
||||||
// Add the client object to the IO instance
|
console.log("There is an open client");
|
||||||
|
|
||||||
|
console.log("Connecting to channel")
|
||||||
const connection = connectToChannel(joinData.channelID);
|
const connection = connectToChannel(joinData.channelID);
|
||||||
console.log("Bot Connected to VC::");
|
console.log("Bot Connected to VC::");
|
||||||
res(connection);
|
res(connection);
|
||||||
@@ -46,10 +58,13 @@ export const leaveDiscordVC = async (guildId) => {
|
|||||||
console.log("Client should remain open: ", clientRemainsOpen);
|
console.log("Client should remain open: ", clientRemainsOpen);
|
||||||
if (!clientRemainsOpen) {
|
if (!clientRemainsOpen) {
|
||||||
console.log("There are no open VC connections");
|
console.log("There are no open VC connections");
|
||||||
// TODO DELETE comment DEV ONLY await closeOP25();
|
await closeOP25();
|
||||||
|
|
||||||
// Close the python client
|
// Close the python client
|
||||||
await requestDiscordClientClose();
|
await requestDiscordClientClose();
|
||||||
|
|
||||||
|
// Close the IPC server
|
||||||
|
await closePdabSocketServer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import { spawn } from "child_process";
|
import { spawn } from "child_process";
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to store references to spawned processes.
|
* Object to store references to spawned processes.
|
||||||
@@ -12,11 +14,11 @@ const runningProcesses = {};
|
|||||||
* @param {string[]} args - The arguments to pass to the process.
|
* @param {string[]} args - The arguments to pass to the process.
|
||||||
* @param {boolean} waitForClose - Set this to wait to return until the process exits
|
* @param {boolean} waitForClose - Set this to wait to return until the process exits
|
||||||
*/
|
*/
|
||||||
export const launchProcess = (processName, args, waitForClose=false, pcwd=undefined) => {
|
export const launchProcess = (processName, args, waitForClose = false, pcwd = undefined) => {
|
||||||
if (!runningProcesses[processName]) {
|
if (!runningProcesses[processName]) {
|
||||||
let childProcess;
|
let childProcess;
|
||||||
if (pcwd) {
|
if (pcwd) {
|
||||||
childProcess = spawn(processName, args, {cwd: pcwd});
|
childProcess = spawn(processName, args, { cwd: pcwd });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
childProcess = spawn(processName, args);
|
childProcess = spawn(processName, args);
|
||||||
@@ -25,11 +27,29 @@ export const launchProcess = (processName, args, waitForClose=false, pcwd=undefi
|
|||||||
// Store reference to the spawned process
|
// Store reference to the spawned process
|
||||||
runningProcesses[processName] = childProcess;
|
runningProcesses[processName] = childProcess;
|
||||||
|
|
||||||
|
// Output the process output in development
|
||||||
|
var scriptOutput = "";
|
||||||
|
|
||||||
|
// Get the stdout from the child process
|
||||||
|
childProcess.stdout.setEncoding('utf8');
|
||||||
|
childProcess.stdout.on('data', (data) => {
|
||||||
|
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data);
|
||||||
|
scriptOutput += data.toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get the stderr from the child process
|
||||||
|
childProcess.stderr.setEncoding('utf8');
|
||||||
|
childProcess.stderr.on('data', (data) => {
|
||||||
|
if (process.env.NODE_ENV === "development") console.log(`Data from ${processName}:`, data);
|
||||||
|
scriptOutput += data.toString();
|
||||||
|
})
|
||||||
|
|
||||||
let code = new Promise(res => {
|
let code = new Promise(res => {
|
||||||
childProcess.on('exit', (code, signal) => {
|
childProcess.on('exit', (code, signal) => {
|
||||||
// Remove reference to the process when it exits
|
// Remove reference to the process when it exits
|
||||||
delete runningProcesses[processName];
|
delete runningProcesses[processName];
|
||||||
console.log(`${processName} process exited with code ${code} and signal ${signal}`);
|
console.log(`${processName} process exited with code ${code} and signal ${signal}`);
|
||||||
|
console.log("Child process console output: ", scriptOutput);
|
||||||
res(code);
|
res(code);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|||||||
232
client/package-lock.json
generated
232
client/package-lock.json
generated
@@ -10,6 +10,7 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/voice": "^0.16.1",
|
"@discordjs/voice": "^0.16.1",
|
||||||
|
"chai-http": "^4.4.0",
|
||||||
"convert-units": "^2.3.4",
|
"convert-units": "^2.3.4",
|
||||||
"discord.js": "^14.14.1",
|
"discord.js": "^14.14.1",
|
||||||
"dotenv": "^16.3.1",
|
"dotenv": "^16.3.1",
|
||||||
@@ -236,11 +237,21 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz",
|
||||||
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
"integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/chai": {
|
||||||
|
"version": "4.3.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.14.tgz",
|
||||||
|
"integrity": "sha512-Wj71sXE4Q4AkGdG9Tvq1u/fquNz9EdG4LIJMwVVII7ashjD/8cf8fyIfJAjRr6YcsXnSE8cOGQPq1gqeR8z+3w=="
|
||||||
|
},
|
||||||
"node_modules/@types/cookie": {
|
"node_modules/@types/cookie": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz",
|
||||||
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
"integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/cookiejar": {
|
||||||
|
"version": "2.1.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.5.tgz",
|
||||||
|
"integrity": "sha512-he+DHOWReW0nghN24E1WUqM0efK4kI9oTqDm6XmK8ZPe2djZ90BSNdGnIyCLzCPw7/pogPlGbzI2wHGGmi4O/Q=="
|
||||||
|
},
|
||||||
"node_modules/@types/cors": {
|
"node_modules/@types/cors": {
|
||||||
"version": "2.8.17",
|
"version": "2.8.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz",
|
||||||
@@ -257,6 +268,15 @@
|
|||||||
"undici-types": "~5.26.4"
|
"undici-types": "~5.26.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/superagent": {
|
||||||
|
"version": "4.1.13",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-4.1.13.tgz",
|
||||||
|
"integrity": "sha512-YIGelp3ZyMiH0/A09PMAORO0EBGlF5xIKfDpK74wdYvWUs2o96b5CItJcWPdH409b7SAXIIG6p8NdU/4U2Maww==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/cookiejar": "*",
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/ws": {
|
"node_modules/@types/ws": {
|
||||||
"version": "8.5.10",
|
"version": "8.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.10.tgz",
|
||||||
@@ -341,6 +361,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/asap": {
|
||||||
|
"version": "2.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
|
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||||
|
},
|
||||||
"node_modules/assertion-error": {
|
"node_modules/assertion-error": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
|
||||||
@@ -350,6 +375,11 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/asynckit": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||||
|
},
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
@@ -491,6 +521,38 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/chai-http": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-uswN3rZpawlRaa5NiDUHcDZ3v2dw5QgLyAwnQ2tnVNuP7CwIsOFuYJ0xR1WiR7ymD4roBnJIzOUep7w9jQMFJA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/chai": "4",
|
||||||
|
"@types/superagent": "4.1.13",
|
||||||
|
"charset": "^1.0.1",
|
||||||
|
"cookiejar": "^2.1.4",
|
||||||
|
"is-ip": "^2.0.0",
|
||||||
|
"methods": "^1.1.2",
|
||||||
|
"qs": "^6.11.2",
|
||||||
|
"superagent": "^8.0.9"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/chai-http/node_modules/qs": {
|
||||||
|
"version": "6.12.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz",
|
||||||
|
"integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==",
|
||||||
|
"dependencies": {
|
||||||
|
"side-channel": "^1.0.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.6"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/chalk": {
|
"node_modules/chalk": {
|
||||||
"version": "4.1.2",
|
"version": "4.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
|
||||||
@@ -506,6 +568,14 @@
|
|||||||
"url": "https://github.com/chalk/chalk?sponsor=1"
|
"url": "https://github.com/chalk/chalk?sponsor=1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/charset": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/charset/-/charset-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/check-error": {
|
"node_modules/check-error": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.0.0.tgz",
|
||||||
@@ -571,6 +641,25 @@
|
|||||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
|
||||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||||
},
|
},
|
||||||
|
"node_modules/combined-stream": {
|
||||||
|
"version": "1.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||||
|
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||||
|
"dependencies": {
|
||||||
|
"delayed-stream": "~1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/component-emitter": {
|
||||||
|
"version": "1.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
|
||||||
|
"integrity": "sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||||
@@ -612,6 +701,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/cookiejar": {
|
||||||
|
"version": "2.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz",
|
||||||
|
"integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw=="
|
||||||
|
},
|
||||||
"node_modules/cors": {
|
"node_modules/cors": {
|
||||||
"version": "2.8.5",
|
"version": "2.8.5",
|
||||||
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
@@ -677,6 +771,14 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/delayed-stream": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=0.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/depd": {
|
"node_modules/depd": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||||
@@ -694,6 +796,15 @@
|
|||||||
"npm": "1.2.8000 || >= 1.4.16"
|
"npm": "1.2.8000 || >= 1.4.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dezalgo": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==",
|
||||||
|
"dependencies": {
|
||||||
|
"asap": "^2.0.0",
|
||||||
|
"wrappy": "1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/diff": {
|
"node_modules/diff": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||||
@@ -948,6 +1059,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||||
},
|
},
|
||||||
|
"node_modules/fast-safe-stringify": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA=="
|
||||||
|
},
|
||||||
"node_modules/fill-range": {
|
"node_modules/fill-range": {
|
||||||
"version": "7.0.1",
|
"version": "7.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||||
@@ -1015,6 +1131,33 @@
|
|||||||
"flat": "cli.js"
|
"flat": "cli.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/formidable": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/formidable/-/formidable-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-CM3GuJ57US06mlpQ47YcunuUZ9jpm8Vx+P2CGt2j7HpgkKZO/DJYQ0Bobim8G6PFQmK5lOqOOdUXboU+h73A4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"dezalgo": "^1.0.4",
|
||||||
|
"hexoid": "^1.0.0",
|
||||||
|
"once": "^1.4.0",
|
||||||
|
"qs": "^6.11.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://ko-fi.com/tunnckoCore/commissions"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/forwarded": {
|
"node_modules/forwarded": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
@@ -1195,6 +1338,14 @@
|
|||||||
"he": "bin/he"
|
"he": "bin/he"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hexoid": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/hexoid/-/hexoid-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-QFLV0taWQOZtvIRIAdBChesmogZrtuXvVWsFHZTk2SU+anspqZ2vMnoLg7IE1+Uk16N19APic1BuF8bC8c2m5g==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/http-errors": {
|
"node_modules/http-errors": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||||
@@ -1235,6 +1386,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/ip-regex": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||||
@@ -1284,6 +1443,17 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/is-ip": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-9MTn0dteHETtyUx8pxqMwg5hMBi3pvlyglJ+b79KOCca0po23337LbVV2Hl4xmMvfw++ljnO0/+5G6G+0Szh6g==",
|
||||||
|
"dependencies": {
|
||||||
|
"ip-regex": "^2.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/is-number": {
|
"node_modules/is-number": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||||
@@ -1543,6 +1713,17 @@
|
|||||||
"get-func-name": "^2.0.1"
|
"get-func-name": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dependencies": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-bytes.js": {
|
"node_modules/magic-bytes.js": {
|
||||||
"version": "1.7.0",
|
"version": "1.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/magic-bytes.js/-/magic-bytes.js-1.7.0.tgz",
|
||||||
@@ -1988,6 +2169,20 @@
|
|||||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "7.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
|
||||||
|
"integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/send": {
|
"node_modules/send": {
|
||||||
"version": "0.18.0",
|
"version": "0.18.0",
|
||||||
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
|
||||||
@@ -2200,6 +2395,38 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/superagent": {
|
||||||
|
"version": "8.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/superagent/-/superagent-8.1.2.tgz",
|
||||||
|
"integrity": "sha512-6WTxW1EB6yCxV5VFOIPQruWGHqc3yI7hEmZK6h+pyk69Lk/Ut7rLUY6W/ONF2MjBuGjvmMiIpsrVJ2vjrHlslA==",
|
||||||
|
"deprecated": "Please upgrade to v9.0.0+ as we have fixed a public vulnerability with formidable dependency. Note that v9.0.0+ requires Node.js v14.18.0+. See https://github.com/ladjs/superagent/pull/1800 for insight. This project is supported and maintained by the team at Forward Email @ https://forwardemail.net",
|
||||||
|
"dependencies": {
|
||||||
|
"component-emitter": "^1.3.0",
|
||||||
|
"cookiejar": "^2.1.4",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"fast-safe-stringify": "^2.1.1",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"formidable": "^2.1.2",
|
||||||
|
"methods": "^1.1.2",
|
||||||
|
"mime": "2.6.0",
|
||||||
|
"qs": "^6.11.0",
|
||||||
|
"semver": "^7.3.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6.4.0 <13 || >=14"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/superagent/node_modules/mime": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/supports-color": {
|
"node_modules/supports-color": {
|
||||||
"version": "7.2.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
@@ -2369,6 +2596,11 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||||
|
},
|
||||||
"node_modules/yargs": {
|
"node_modules/yargs": {
|
||||||
"version": "17.7.2",
|
"version": "17.7.2",
|
||||||
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
"resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
"socket.io-client": "^4.7.2"
|
"socket.io-client": "^4.7.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"chai-http": "^4.4.0",
|
||||||
"chai": "^5.1.0",
|
"chai": "^5.1.0",
|
||||||
"mocha": "^10.4.0",
|
"mocha": "^10.4.0",
|
||||||
"typescript": "^5.3.3"
|
"typescript": "^5.3.3"
|
||||||
|
|||||||
@@ -1,3 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Install client package updates
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
|
# Install OP25 Updates
|
||||||
|
#cd ./op25
|
||||||
|
#bash rebuild.sh
|
||||||
|
|
||||||
|
# Check for PDAB updates
|
||||||
|
cd ../discordAudioBot/pdab
|
||||||
|
git pull
|
||||||
113
client/setup.sh
113
client/setup.sh
@@ -16,46 +16,76 @@ if [[ ! -f "$(pwd)/package.json" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Check to make sure the pi user exists
|
||||||
|
if ! id "pi" &>/dev/null; then
|
||||||
|
echo "Error: User pi does not exist."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
####------------------- Functions
|
####------------------- Functions
|
||||||
# Function to prompt user for input with a specific message and store the result in a variable
|
# Function to prompt user for input with a specific message and store the result in a variable
|
||||||
prompt_user() {
|
prompt_user() {
|
||||||
read -p "$1: " input
|
if [[ "$TEST_MODE" == "true" ]]; then
|
||||||
echo "$input"
|
echo "TESTING" # Use the pre-set value
|
||||||
|
else
|
||||||
|
read -p "$1: " input
|
||||||
|
echo "$input"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to prompt user for capabilities options and store the result in a variable
|
# Function to prompt user for capabilities options and store the result in a variable
|
||||||
prompt_capabilities() {
|
prompt_capabilities() {
|
||||||
default_capabilities="radio" # Default value
|
if [[ "$TEST_MODE" == "true" ]]; then
|
||||||
read -p "Select CLIENT_CAPABILITIES (comma-separated, default: $default_capabilities): " capabilities
|
echo "radio" # Use the pre-set value
|
||||||
capabilities="${capabilities:-$default_capabilities}" # Use default value if input is empty
|
else
|
||||||
echo "$capabilities"
|
default_capabilities="radio" # Default value
|
||||||
|
read -p "Select CLIENT_CAPABILITIES (comma-separated, default: $default_capabilities): " capabilities
|
||||||
|
capabilities="${capabilities:-$default_capabilities}" # Use default value if input is empty
|
||||||
|
echo "$capabilities"
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to prompt user for nearby systems details
|
# Function to prompt user for nearby systems details
|
||||||
prompt_nearby_system() {
|
prompt_nearby_system() {
|
||||||
local system_name=""
|
if [[ "$TEST_MODE" == "true" ]]; then
|
||||||
local frequencies=""
|
echo "\"TESTING-Node\": {
|
||||||
local mode=""
|
\"frequencies\": [\"$(echo "155750000,154750000,156555550" | sed 's/,/","/g')\"],
|
||||||
local trunk_file=""
|
\"mode\": \"p25\",
|
||||||
local whitelist_file=""
|
\"trunkFile\": \"testing_trunk.tsv\",
|
||||||
|
\"whitelistFile\": \"testing_whitelist.tsv\"
|
||||||
|
}," # Use the pre-set value
|
||||||
|
else
|
||||||
|
local system_name=""
|
||||||
|
local frequencies=""
|
||||||
|
local mode=""
|
||||||
|
local trunk_file=""
|
||||||
|
local whitelist_file=""
|
||||||
|
|
||||||
read -p "Enter system name: " system_name
|
read -p "Enter system name: " system_name
|
||||||
read -p "Enter frequencies (comma-separated): " frequencies
|
read -p "Enter frequencies (comma-separated): " frequencies
|
||||||
read -p "Enter mode (p25/nbfm): " mode
|
read -p "Enter mode (p25/nbfm): " mode
|
||||||
|
|
||||||
if [[ "$mode" == "p25" ]]; then
|
if [[ "$mode" == "p25" ]]; then
|
||||||
read -p "Enter trunk file: " trunk_file
|
read -p "Enter trunk file: " trunk_file
|
||||||
read -p "Enter whitelist file: " whitelist_file
|
read -p "Enter whitelist file: " whitelist_file
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "\"$system_name\": {
|
||||||
|
\"frequencies\": [\"$(echo "$frequencies" | sed 's/,/","/g')\"],
|
||||||
|
\"mode\": \"$mode\",
|
||||||
|
\"trunkFile\": \"$trunk_file\",
|
||||||
|
\"whitelistFile\": \"$whitelist_file\"
|
||||||
|
},"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "\"$system_name\": {
|
|
||||||
\"frequencies\": [\"$(echo "$frequencies" | sed 's/,/","/g')\"],
|
|
||||||
\"mode\": \"$mode\",
|
|
||||||
\"trunkFile\": \"$trunk_file\",
|
|
||||||
\"whitelistFile\": \"$whitelist_file\"
|
|
||||||
},"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Check if test mode is enabled
|
||||||
|
if [[ "$1" == "--test" ]]; then
|
||||||
|
TEST_MODE="true"
|
||||||
|
else
|
||||||
|
TEST_MODE="false"
|
||||||
|
fi
|
||||||
|
|
||||||
# Install Node Repo
|
# Install Node Repo
|
||||||
# Get the CPU architecture
|
# Get the CPU architecture
|
||||||
cpu_arch=$(uname -m)
|
cpu_arch=$(uname -m)
|
||||||
@@ -68,6 +98,7 @@ if [[ "$cpu_arch" == "armv6"* ]]; then
|
|||||||
echo "----- CPU Architecture is ARMv6 or compatible. -----"
|
echo "----- CPU Architecture is ARMv6 or compatible. -----"
|
||||||
echo "----- CPU Architectre is not compatible with dependencies of this project, please use a newer CPU architecture -----"
|
echo "----- CPU Architectre is not compatible with dependencies of this project, please use a newer CPU architecture -----"
|
||||||
exit
|
exit
|
||||||
|
fi
|
||||||
|
|
||||||
curl -fsSL https://deb.nodesource.com/setup_current.x | sudo -E bash -
|
curl -fsSL https://deb.nodesource.com/setup_current.x | sudo -E bash -
|
||||||
|
|
||||||
@@ -77,7 +108,18 @@ apt upgrade -y
|
|||||||
|
|
||||||
# Install the necessary packages
|
# Install the necessary packages
|
||||||
echo "Installing dependencies..."
|
echo "Installing dependencies..."
|
||||||
apt install -y nodejs portaudio19-dev libportaudio2 libpulse-dev pulseaudio apulse git ffmpeg git
|
apt install -y \
|
||||||
|
nodejs \
|
||||||
|
libasound-dev \
|
||||||
|
portaudio19-dev \
|
||||||
|
libportaudio2 \
|
||||||
|
libpulse-dev \
|
||||||
|
pulseaudio \
|
||||||
|
apulse \
|
||||||
|
git \
|
||||||
|
ffmpeg \
|
||||||
|
python3 \
|
||||||
|
python3-pip
|
||||||
|
|
||||||
echo "Setting up Pulse Audio"
|
echo "Setting up Pulse Audio"
|
||||||
|
|
||||||
@@ -104,13 +146,21 @@ usermod -aG pulse-access pi
|
|||||||
|
|
||||||
# Enable the PulseAudio service
|
# Enable the PulseAudio service
|
||||||
systemctl enable PulseAudio.service
|
systemctl enable PulseAudio.service
|
||||||
systemctl stop PulseAudio.service
|
|
||||||
|
|
||||||
####------------------- Install and setup node
|
####------------------- Install and setup node
|
||||||
# Run npm install to install dependencies listed in package.json
|
# Run npm install to install dependencies listed in package.json
|
||||||
echo "Installing npm dependencies..."
|
echo "Installing npm dependencies..."
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
|
# Get rid of PEP 668
|
||||||
|
rm -rf /usr/lib/python3.11/EMTERNALL-MANAGED # Not sure if this was an attrocious fat finger or if this is needed, doesn't throw an error, so...
|
||||||
|
rm -rf /usr/lib/python3.11/EXTERNALLY-MANAGED
|
||||||
|
|
||||||
|
# Getting the Python DAB
|
||||||
|
echo "Installing PDAB and Dependencies"
|
||||||
|
git clone -b DRBv3 https://git.vpn.cusano.net/logan/Python-Discord-Audio-Bot.git ./discordAudioBot/pdab
|
||||||
|
pip3 install -r ./discordAudioBot/pdab/requirements.txt
|
||||||
|
|
||||||
# Generate .env file
|
# Generate .env file
|
||||||
echo "Creating the config .env file..."
|
echo "Creating the config .env file..."
|
||||||
echo "# Client Config" > .env
|
echo "# Client Config" > .env
|
||||||
@@ -138,6 +188,11 @@ echo "OP25_FULL_PATH=$op25_full_path" >> .env
|
|||||||
echo "" >> .env
|
echo "" >> .env
|
||||||
echo "# Core config, DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING" >> .env
|
echo "# Core config, DO NOT TOUCH UNLESS YOU KNOW WHAT YOU ARE DOING" >> .env
|
||||||
echo "CONFIG_PATH=./config/radioPresets.json" >> .env
|
echo "CONFIG_PATH=./config/radioPresets.json" >> .env
|
||||||
|
runuser -l pi -c 'python3 ./discordAudioBot/pdab/getDevices.py'
|
||||||
|
audio_device_id=$(prompt_user "Enter the ID of the 'input' audio device you would like to use (most often 'default')")
|
||||||
|
echo "AUDIO_DEVICE_ID=$audio_device_id" >> .env
|
||||||
|
echo "PDAB_PORT=3110" >> .env
|
||||||
|
echo "NODE_ENV=production" >> .env
|
||||||
|
|
||||||
echo ".env file generated successfully."
|
echo ".env file generated successfully."
|
||||||
|
|
||||||
@@ -183,14 +238,13 @@ echo "$service_content" > /etc/systemd/system/discord-radio-bot.service
|
|||||||
# Reload systemd daemon
|
# Reload systemd daemon
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl enable discord-radio-bot.service
|
systemctl enable discord-radio-bot.service
|
||||||
systemctl stop discord-radio-bot.service
|
|
||||||
|
|
||||||
echo "\n\n\t\tDiscord Client Node install completed!\n\n"
|
echo "\n\n\t\tDiscord Client Node install completed!\n\n"
|
||||||
|
|
||||||
####------------------- OP25 Installation
|
####------------------- OP25 Installation
|
||||||
# Clone OP25 from the git repository
|
# Clone OP25 from the git repository
|
||||||
echo "Cloning OP25 from the git repository..."
|
echo "Cloning OP25 from the git repository..."
|
||||||
git clone https://github.com/boatbod/op25.git
|
git clone -b gr310 https://github.com/boatbod/op25.git
|
||||||
|
|
||||||
# Navigate to the OP25 directory
|
# Navigate to the OP25 directory
|
||||||
ogPwd=$(pwd)
|
ogPwd=$(pwd)
|
||||||
@@ -226,7 +280,6 @@ echo "$service_content" > /etc/systemd/system/op25-multi_rx.service
|
|||||||
|
|
||||||
# Reload systemd daemon
|
# Reload systemd daemon
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl stop op25-multi_rx.service
|
|
||||||
|
|
||||||
# Install OP25 using the provided installation script
|
# Install OP25 using the provided installation script
|
||||||
echo "Installing OP25..."
|
echo "Installing OP25..."
|
||||||
@@ -251,7 +304,7 @@ confirm="${confirm,,}"
|
|||||||
#echo "To configure the app, please go to http://$nodeIP:$nodePort" # TODO - uncomment when webapp is built
|
#echo "To configure the app, please go to http://$nodeIP:$nodePort" # TODO - uncomment when webapp is built
|
||||||
echo "Thank you for joining the network!"
|
echo "Thank you for joining the network!"
|
||||||
|
|
||||||
if [[ "$confirm" != "y" && "$confirm" != "yes" ]]; then
|
if [[ "$confirm" == "y" && "$confirm" == "yes" ]]; then
|
||||||
# Prompt user to press any key before rebooting
|
# Prompt user to press any key before rebooting
|
||||||
read -rsp $'System will now reboot, press any key to continue or Ctrl+C to cancel...\n' -n1 key
|
read -rsp $'System will now reboot, press any key to continue or Ctrl+C to cancel...\n' -n1 key
|
||||||
echo "Rebooting..."
|
echo "Rebooting..."
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
// Import necessary modules for testing
|
// Import necessary modules for testing
|
||||||
import { expect } from 'chai';
|
import { expect } from 'chai'
|
||||||
import io from 'socket.io-client';
|
import io from 'socket.io-client';
|
||||||
|
const ioClient = io;
|
||||||
|
|
||||||
import dotenv from 'dotenv';
|
import dotenv from 'dotenv';
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|
||||||
process.env.DISCORD_CLIENT_ID = "MTE5NjAwNTM2ODYzNjExMjk3Nw.GuCMXg.24iNNofNNumq46FIj68zMe9RmQgugAgfrvelEA"
|
|
||||||
process.env.TEST_CHANNEL_ID = 757417670466469989
|
|
||||||
process.env.TEST_GUILD_ID = 367396189529833472
|
|
||||||
process.env.EXPECTED_CLIENT_ID = 1196005368636112977
|
|
||||||
process.env.NODE_ENV = 'development'
|
|
||||||
process.env.PDAB_PORT = 3110
|
|
||||||
|
|
||||||
import { initDiscordBotClient, connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, requestDiscordUsername, requestDiscordID, requestDiscordClientClose, closePdabSocketServer } from '../discordAudioBot/pdabHandler.mjs';
|
import { initDiscordBotClient, connectToChannel, leaveVoiceChannel, checkIfConnectedToVC, requestDiscordUsername, requestDiscordID, requestDiscordClientClose, closePdabSocketServer } from '../discordAudioBot/pdabHandler.mjs';
|
||||||
|
|
||||||
let socket;
|
let socket;
|
||||||
@@ -22,32 +16,31 @@ before(async done => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
after(async () => {
|
after(async () => {
|
||||||
// Any teardown needed after tests
|
|
||||||
try{
|
|
||||||
await socket.close();
|
|
||||||
}
|
|
||||||
catch {
|
|
||||||
console.log("Socket already closed");
|
|
||||||
}
|
|
||||||
console.log('Closing PDAB Socker Server');
|
|
||||||
await closePdabSocketServer();
|
await closePdabSocketServer();
|
||||||
});
|
})
|
||||||
|
|
||||||
|
describe('Socket Server Tests', done => {
|
||||||
|
after(async () => {
|
||||||
|
// Any teardown needed after tests
|
||||||
|
try {
|
||||||
|
await socket.close();
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
console.log("Socket already closed");
|
||||||
|
}
|
||||||
|
console.log('Closing PDAB Socker Server');
|
||||||
|
});
|
||||||
|
|
||||||
describe('Python Discord Bot Socket IPC Tests', done => {
|
|
||||||
it('Should open a socket server and callback when the client is connected and ready', done => {
|
it('Should open a socket server and callback when the client is connected and ready', done => {
|
||||||
let clientConnected = false;
|
const clientId = process.env.TEST_CLIENT_TOKEN;
|
||||||
const clientId = process.env.DISCORD_CLIENT_ID;
|
|
||||||
|
|
||||||
const callback = () => {
|
const callback = () => {
|
||||||
clientConnected = true;
|
|
||||||
expect(clientConnected).to.be.true;
|
|
||||||
|
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|
||||||
initDiscordBotClient(clientId, callback);
|
initDiscordBotClient(clientId, callback, false);
|
||||||
|
|
||||||
socket = io.connect(`http://localhost:${process.env.PDAB_PORT}`);
|
socket = ioClient.connect(`http://localhost:${process.env.PDAB_PORT}`);
|
||||||
|
|
||||||
socket.on('connect', () => {
|
socket.on('connect', () => {
|
||||||
socket.emit('discord_ready')
|
socket.emit('discord_ready')
|
||||||
@@ -102,13 +95,13 @@ describe('Python Discord Bot Socket IPC Tests', done => {
|
|||||||
socket.on('request_discord_username', (data, callback) => {
|
socket.on('request_discord_username', (data, callback) => {
|
||||||
console.log('Username Check data:', data);
|
console.log('Username Check data:', data);
|
||||||
expect(data).to.deep.equal({ guildId: process.env.TEST_GUILD_ID });
|
expect(data).to.deep.equal({ guildId: process.env.TEST_GUILD_ID });
|
||||||
callback('!bot-username');
|
callback(process.env.EXPECTED_USERNAME);
|
||||||
});
|
});
|
||||||
// Simulate emitting 'request_discord_username' event
|
// Simulate emitting 'request_discord_username' event
|
||||||
const username = await requestDiscordUsername(process.env.TEST_GUILD_ID);
|
const username = await requestDiscordUsername(process.env.TEST_GUILD_ID);
|
||||||
|
|
||||||
// Assert the username returned from the server
|
// Assert the username returned from the server
|
||||||
expect(username).to.equal("!bot-username");
|
expect(username).to.equal(process.env.EXPECTED_USERNAME);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should emit command for and return discord client ID', async () => {
|
it('Should emit command for and return discord client ID', async () => {
|
||||||
@@ -132,3 +125,70 @@ describe('Python Discord Bot Socket IPC Tests', done => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Socket Client & Python IPC Tests', done => {
|
||||||
|
it('Should open a socket server and callback when the client is connected and ready', done => {
|
||||||
|
let clientConnected = false;
|
||||||
|
const clientId = process.env.TEST_CLIENT_TOKEN;
|
||||||
|
|
||||||
|
const callback = () => {
|
||||||
|
clientConnected = true;
|
||||||
|
expect(clientConnected).to.be.true;
|
||||||
|
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
initDiscordBotClient(clientId, callback);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for and return status from join server', async () => {
|
||||||
|
// Simulate emitting 'join_server' event
|
||||||
|
const status = await connectToChannel(process.env.TEST_CHANNEL_ID);
|
||||||
|
|
||||||
|
// Check the server sent the expected info
|
||||||
|
|
||||||
|
// Assert the status returned from the server
|
||||||
|
expect(status).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for and return status if connected to voice channel', async () => {
|
||||||
|
// Simulate emitting 'check_discord_vc_connected' event
|
||||||
|
const isConnected = await checkIfConnectedToVC(process.env.TEST_GUILD_ID);
|
||||||
|
|
||||||
|
// Assert the connection status returned from the server
|
||||||
|
expect(isConnected).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for and return username for request discord username', async () => {
|
||||||
|
// Simulate emitting 'request_discord_username' event
|
||||||
|
const username = await requestDiscordUsername(process.env.TEST_GUILD_ID);
|
||||||
|
|
||||||
|
// Assert the username returned from the server
|
||||||
|
expect(username).to.equal(process.env.EXPECTED_USERNAME);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for and return discord client ID', async () => {
|
||||||
|
// Simulate emitting 'request_discord_id' event
|
||||||
|
const clientId = await requestDiscordID();
|
||||||
|
|
||||||
|
console.log("type of client id", typeof clientId, typeof process.env.EXPECTED_CLIENT_ID);
|
||||||
|
|
||||||
|
// Assert the client ID returned from the server
|
||||||
|
expect(clientId).to.equal(Number(process.env.EXPECTED_CLIENT_ID));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for and return open status for leave server', async () => {
|
||||||
|
// Simulate emitting 'leave_server' event
|
||||||
|
const openStatus = await leaveVoiceChannel(process.env.TEST_GUILD_ID);
|
||||||
|
|
||||||
|
// Assert the open status returned from the server
|
||||||
|
expect(openStatus).to.be.false;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should emit command for discord client to close', async () => {
|
||||||
|
// Simulate emitting 'request_client_close' event
|
||||||
|
await requestDiscordClientClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
40
client/test/pdabWrappers.test.js.bak
Normal file
40
client/test/pdabWrappers.test.js.bak
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { use } from 'chai';
|
||||||
|
import chaiHttp from 'chai-http';
|
||||||
|
const chai = use(chaiHttp)
|
||||||
|
chai.should();
|
||||||
|
|
||||||
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config()
|
||||||
|
|
||||||
|
import { joinDiscordVC, leaveDiscordVC } from '../discordAudioBot/pdabWrappers.mjs'
|
||||||
|
|
||||||
|
before(async () => {
|
||||||
|
// Any setup needed before tests
|
||||||
|
});
|
||||||
|
|
||||||
|
after(async () => {
|
||||||
|
// Any teardown needed after tests
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('PDAB Wrapper Tests', () => {
|
||||||
|
it('Should open the discord bot, and join the first server when requested', async () => {
|
||||||
|
// Test case
|
||||||
|
const joinData = {
|
||||||
|
channelID: process.env.TEST_CHANNEL_ID,
|
||||||
|
clientID: process.env.TEST_CLIENT_TOKEN,
|
||||||
|
system: process.env.TEST_SYSTEM,
|
||||||
|
};
|
||||||
|
const connection = await joinDiscordVC(joinData);
|
||||||
|
console.log("Connection:", connection);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should open OP25', async () => {
|
||||||
|
const res = await chai.request('http://localhost:8081').get('/');
|
||||||
|
expect(res).to.have.status(200); // Assuming 200 is the expected status code
|
||||||
|
// Add more assertions if needed
|
||||||
|
})
|
||||||
|
|
||||||
|
it("Should disconnect from the discord server", async () => {
|
||||||
|
await leaveDiscordVC(process.env.TEST_GUILD_ID);
|
||||||
|
})
|
||||||
|
});
|
||||||
21
server/Dockerfile
Normal file
21
server/Dockerfile
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Use the official Node.js image as the base image
|
||||||
|
FROM node:20
|
||||||
|
|
||||||
|
# Set the working directory inside the container
|
||||||
|
WORKDIR /server
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json (if available) to the working directory
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm install -g node-gyp
|
||||||
|
RUN npm install
|
||||||
|
|
||||||
|
# Copy the rest of the application code to the working directory
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Expose the port on which your Node.js application will run
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# Command to run the Node.js application
|
||||||
|
CMD ["node", "."]
|
||||||
@@ -41,9 +41,10 @@ export async function autocomplete(nodeIo, interaction) {
|
|||||||
*/
|
*/
|
||||||
export async function execute(nodeIo, interaction) {
|
export async function execute(nodeIo, interaction) {
|
||||||
// Check if the user is in a VC
|
// Check if the user is in a VC
|
||||||
if (!interaction.member.voice.channel) { return await interaction.editReply({ content: `<@${interaction.member.id}>, you need to enter a voice channel before use the command`, ephemeral: true }) }
|
if (!interaction.member.voice.channel) { return await interaction.editReply({ content: `<@${interaction.member.id}>, you need to enter a voice channel before you use this command`, ephemeral: true }) }
|
||||||
// Grab the channel if the user is connected to VC
|
// Grab the channel if the user is connected to VC
|
||||||
const channelToJoin = interaction.member.voice.channel;
|
const channelToJoin = interaction.member.voice.channel;
|
||||||
|
console.log(`The user '${interaction.member.id}' is in the voice channel '${channelToJoin}'`);
|
||||||
|
|
||||||
// Get the selected system option from the command interaction
|
// Get the selected system option from the command interaction
|
||||||
const selectedSystem = interaction.options.getString('system');
|
const selectedSystem = interaction.options.getString('system');
|
||||||
@@ -56,13 +57,19 @@ export async function execute(nodeIo, interaction) {
|
|||||||
const joinSelectedNode = async (selectedNodeSocketId) => {
|
const joinSelectedNode = async (selectedNodeSocketId) => {
|
||||||
const openSocket = await nodeIo.sockets.sockets.get(selectedNodeSocketId);
|
const openSocket = await nodeIo.sockets.sockets.get(selectedNodeSocketId);
|
||||||
// Get the open ID for this connection\
|
// Get the open ID for this connection\
|
||||||
const discordToken = await getAvailableTokensInGuild(nodeIo, interaction.guild.id);
|
const ss = await getAvailableTokensInGuild(nodeIo, interaction.guild.id);
|
||||||
// TODO - Implement a method to have preferred tokens (bot users) for specific systems
|
console.log("Available discord tokens: ", discordTokens);
|
||||||
|
|
||||||
console.log("Joining selected open socket:", selectedNodeSocketId, system.name, channelToJoin.id, openSocket.node.name, discordToken);
|
if (discordTokens.length >= 1) {
|
||||||
|
// TODO - Implement a method to have preferred tokens (bot users) for specific systems
|
||||||
|
console.log("Joining selected open socket:", selectedNodeSocketId, system.name, channelToJoin.id, openSocket.node.name, discordTokens[0].token);
|
||||||
|
|
||||||
// Ask the node to join the selected channel and system
|
// Ask the node to join the selected channel and system
|
||||||
await requestNodeJoinSystem(openSocket, system.name, channelToJoin.id, discordToken[0].token);
|
await requestNodeJoinSystem(openSocket, system.name, channelToJoin.id, discordTokens[0].token);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return await interaction.editReply({ content: `<@${interaction.member.id}>, there are no free bots. Free up or create a new bot ID (discord app) to listen to this system.`, ephemeral: true })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get all open socket nodes
|
// Get all open socket nodes
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ export function addEnabledEventListeners(serverClient, _eventsPath = "./events")
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The discord client
|
// The discord client
|
||||||
export const serverClient = new Client({ intents: [GatewayIntentBits.Guilds] });
|
export const serverClient = new Client({ intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildVoiceStates] });
|
||||||
|
|
||||||
// Run when the bot is ready
|
// Run when the bot is ready
|
||||||
serverClient.on('ready', async () => {
|
serverClient.on('ready', async () => {
|
||||||
|
|||||||
@@ -37,10 +37,7 @@ export const checkOnlineBotsInGuild = async (nodeIo, guildId) => {
|
|||||||
console.log("Online bots in the guild:", onlineBots);
|
console.log("Online bots in the guild:", onlineBots);
|
||||||
|
|
||||||
// Filter any discordIDs that are not active
|
// Filter any discordIDs that are not active
|
||||||
var availableDiscordIDs = discordIDs.filter(discordID => discordID.active == true);
|
const availableDiscordIDs = discordIDs.filter(discordID => discordID.active == true).filter(discordID => !onlineBots.some(bot => Number(bot.discord_id) == discordID.discord_id));
|
||||||
|
|
||||||
// Filter out discordIDs that are not found in onlineBots
|
|
||||||
availableDiscordIDs = availableDiscordIDs.filter(discordID => !onlineBots.some(bot => bot.discord_id === discordID.discord_id));
|
|
||||||
|
|
||||||
// Return the unavailable discordIDs
|
// Return the unavailable discordIDs
|
||||||
return availableDiscordIDs;
|
return availableDiscordIDs;
|
||||||
|
|||||||
25
server/makefile
Normal file
25
server/makefile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# Define variables
|
||||||
|
DOCKER_IMAGE_NAME := drb-server
|
||||||
|
|
||||||
|
# Define targets and rules
|
||||||
|
.PHONY: clean build run
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "Cleaning existing Docker images, containers, and builds..."
|
||||||
|
docker stop drb || true
|
||||||
|
docker rm drb || true
|
||||||
|
docker rmi $(DOCKER_IMAGE_NAME) || true
|
||||||
|
|
||||||
|
build:
|
||||||
|
@echo "Building Docker image..."
|
||||||
|
docker build -t $(DOCKER_IMAGE_NAME) .
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo "Running Docker container..."
|
||||||
|
docker run -d -e NODE_ENV=${NODE_ENV} \
|
||||||
|
-e SERVER_PORT=${SERVER_PORT} \
|
||||||
|
-e MONGO_URL=${MONGO_URL} \
|
||||||
|
-e DISCORD_TOKEN=${DISCORD_TOKEN} \
|
||||||
|
-p ${SERVER_PORT}:${SERVER_PORT} \
|
||||||
|
--name=drb \
|
||||||
|
$(DOCKER_IMAGE_NAME)
|
||||||
Reference in New Issue
Block a user