diff --git a/server/datahandler.js b/server/datahandler.js index 713ba67..41a0bfd 100644 --- a/server/datahandler.js +++ b/server/datahandler.js @@ -130,7 +130,7 @@ function handleData(wss, receivedData, rdsWss) { dataToSend.agc = receivedLine.substring(1); initialData.agc = receivedLine.substring(1); break; - case receivedLine.startsWith('G'): // EQ / iMS (RF+/IF+) + case receivedLine.startsWith('G'): // EQ / iMS const mapping = filterMappings[receivedLine]; if (mapping) { initialData.eq = mapping.eq; @@ -149,13 +149,13 @@ function handleData(wss, receivedData, rdsWss) { case receivedLine.startsWith('Ss'): processSignal(receivedLine, true, false); break; - case receivedLine.startsWith('SS'): + case receivedLine.startsWith('SS'): // ss? oh no processSignal(receivedLine, true, true); break; case receivedLine.startsWith('SM'): processSignal(receivedLine, false, true); break; - case receivedLine.startsWith('R'): // RDS HEX + case receivedLine.startsWith('R'): rdsReceived(); modifiedData = receivedLine.slice(1); dataToSend.rds = true; @@ -202,9 +202,7 @@ function handleData(wss, receivedData, rdsWss) { legacyRdsPiBuffer = null; break; case receivedLine.startsWith("!"): - wss.clients.forEach((client) => { - client.send(receivedLine.trim()); - }); + wss.clients.forEach((client) => client.send(receivedLine.trim())); break; } } @@ -236,9 +234,7 @@ function handleData(wss, receivedData, rdsWss) { // Send the updated data to the client const dataToSendJSON = JSON.stringify(dataToSend); if (currentTime - lastUpdateTime >= updateInterval) { - wss.clients.forEach((client) => { - client.send(dataToSendJSON); - }); + wss.clients.forEach((client) => client.send(dataToSendJSON)); lastUpdateTime = Date.now(); serialportUpdateTime = process.hrtime(); } @@ -307,6 +303,4 @@ function processSignal(receivedData, st, stForced) { } } -module.exports = { - handleData, showOnlineUsers, dataToSend, initialData, resetToDefault, state -}; +module.exports = { handleData, showOnlineUsers, dataToSend, initialData, resetToDefault, state }; diff --git a/server/index.js b/server/index.js index 9cacd01..fa0cbe9 100644 --- a/server/index.js +++ b/server/index.js @@ -28,12 +28,15 @@ const pjson = require('../package.json'); const client = new net.Socket(); const wss = new WebSocket.Server({ noServer: true }); const rdsWss = new WebSocket.Server({ noServer: true }); +const rawComm = new WebSocket.Server({ noServer: true }); const pluginsWss = new WebSocket.Server({ noServer: true, perMessageDeflate: true }); storage.websocket_delegation.set("/text", wss); storage.websocket_delegation.set("/rds", rdsWss); storage.websocket_delegation.set("/rdsspy", rdsWss); +storage.websocket_delegation.set("/rawcomm", rawComm); storage.websocket_delegation.set("/data_plugins", pluginsWss); +require('./stream/ws.js'); // Get all plugins from config and find corresponding server files const plugins = findServerFiles(serverConfig.plugins); @@ -52,8 +55,6 @@ console.log('\x1b[32m\x1b[2mby Noobish @ \x1b[4mFMDX.org + KubaPro010\x1b[0m'); console.log("v" + pjson.version) console.log('\x1b[90m' + '─'.repeat(terminalWidth - 1) + '\x1b[0m'); -require('./stream/ws.js'); -require('./stream/index'); require('./plugins'); let currentUsers = 0; @@ -71,6 +72,7 @@ app.use(bodyParser.json()); createChatServer(storage); tunnel.download(); +require('./stream/index'); connectToXdrd(); connectToSerial(); @@ -146,6 +148,9 @@ function connectToSerial() { serialport.on('data', (data) => { helpers.resolveDataBuffer(data, wss, rdsWss); + rawComm.clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) client.send(data); + }); }); serialport.on('error', (error) => { @@ -191,6 +196,9 @@ client.on('data', (data) => { const { xdrd } = serverConfig; helpers.resolveDataBuffer(data, wss, rdsWss); + rawComm.clients.forEach((client) => { + if (client.readyState === WebSocket.OPEN) client.send(data); + }); if (authFlags.authMsg == true && authFlags.messageCount > 1) return; authFlags.messageCount++; @@ -268,10 +276,6 @@ client.on('error', (err) => { } }); -app.set('view engine', 'ejs'); -app.set('views', path.join(__dirname, '../views')); -app.use('/', endpoints); - const tunerLockTracker = new WeakMap(); const ipConnectionCounts = new Map(); // Per-IP limit variables const ipLogTimestamps = new Map(); @@ -290,7 +294,20 @@ setInterval(() => { ipLogTimestamps.delete(ip); } } -}, 60 * 60 * 1000); // Run every hour +}, 30 * 60 * 1000); // Run every half hour + +rawComm.on('connection', (ws, request) => { + const output = serverConfig.xdrd.wirelessConnection ? client : serialport; + const { isAdminAuthenticated } = request.session || {}; + if(!isAdminAuthenticated) { + ws.close(1008, "No admin"); + return; + } + + ws.on('message', (message) => { + output.write(`${message.toString()}\n`); + }); +}); wss.on('connection', (ws, request) => { const output = serverConfig.xdrd.wirelessConnection ? client : serialport; @@ -300,7 +317,7 @@ wss.on('connection', (ws, request) => { // Per-IP limit connection open if (clientIp) { const isLocalIp = ( - clientIp === '127.0.0.1' || clientIp === '::1' || clientIp === '::ffff:127.0.0.1' || + clientIp === '127.0.0.1' || clientIp === '::1' || clientIp.startsWith('192.168.') || clientIp.startsWith('10.') || clientIp.startsWith('172.16.')); if (!isLocalIp) { if (!ipConnectionCounts.has(clientIp)) ipConnectionCounts.set(clientIp, 0); @@ -402,7 +419,7 @@ wss.on('connection', (ws, request) => { } } - if (clientIp !== '::ffff:127.0.0.1' || + if (clientIp !== ':127.0.0.1' || (request.socket && request.socket.remoteAddress && request.socket.remoteAddress !== '::ffff:127.0.0.1') || (request.headers && request.headers['origin'] && request.headers['origin'].trim() !== '')) { currentUsers--; @@ -521,24 +538,23 @@ httpServer.on('upgrade', (request, socket, head) => { } else socket.destroy(); }); +app.set('view engine', 'ejs'); +app.set('views', path.join(__dirname, '../views')); +app.use('/', endpoints); app.use(express.static(path.join(__dirname, '../web'))); // Serve the entire web folder to the user pluginsApi.registerServerContext({ wss, pluginsWss, httpServer, serverConfig }); -const ipv4Address = serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp; -const port = serverConfig.webserver.webserverPort; - const logServerStart = (address) => { - logInfo(`Web server has started on address \x1b[34mhttp://${address}:${port}\x1b[0m.`); + logInfo(`Web server has started on address \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); }; const startServer = (address) => { - httpServer.listen(port, address, () => { - if (!configExists()) logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${port}\x1b[0m to continue with setup.`); + httpServer.listen(serverConfig.webserver.webserverPort, address, () => { + if (!configExists()) logInfo(`Open your browser and proceed to \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m to continue with setup.`); else logServerStart(address); }); }; - -startServer(ipv4Address); +startServer(serverConfig.webserver.webserverIp === '0.0.0.0' ? 'localhost' : serverConfig.webserver.webserverIp); tunnel.connect(); fmdxList.update(); \ No newline at end of file diff --git a/server/plugins.js b/server/plugins.js index c42e064..dda88f8 100644 --- a/server/plugins.js +++ b/server/plugins.js @@ -2,13 +2,11 @@ const fs = require('fs'); const path = require('path'); const consoleCmd = require('./console'); -// Function to read all .js files in a directory function readJSFiles(dir) { const files = fs.readdirSync(dir); return files.filter(file => file.endsWith('.js')); } -// Function to parse plugin config from a file function parsePluginConfig(filePath) { const pluginConfig = {}; @@ -75,10 +73,10 @@ if (!fs.existsSync(webJsPluginsDir)) fs.mkdirSync(webJsPluginsDir, { recursive: // Main function to create symlinks/junctions for plugins function createLinks() { - const pluginsDir = path.join(__dirname, '../plugins'); - const destinationPluginsDir = path.join(__dirname, '../web/js/plugins'); - if (process.platform === 'win32') { + const pluginsDir = path.join(__dirname, '../plugins'); + const destinationPluginsDir = path.join(__dirname, '../web/js/plugins'); + // On Windows, create a junction try { if (fs.existsSync(destinationPluginsDir)) fs.rmSync(destinationPluginsDir, { recursive: true }); @@ -89,8 +87,6 @@ function createLinks() { } } -// Usage example -const allPluginConfigs = collectPluginConfigs(); +// the usage example comment that was here got me so laughing, that i don't know about all of this createLinks(); - -module.exports = allPluginConfigs; +module.exports = collectPluginConfigs(); diff --git a/server/server_config.js b/server/server_config.js index 064afe9..189b784 100644 --- a/server/server_config.js +++ b/server/server_config.js @@ -187,6 +187,4 @@ if (configExists()) { } -module.exports = { - configName, serverConfig, configUpdate, configSave, configExists, configPath -}; +module.exports = { configName, serverConfig, configUpdate, configSave, configExists, configPath }; diff --git a/server/stream/index.js b/server/stream/index.js index 2e7f73d..dc728b6 100644 --- a/server/stream/index.js +++ b/server/stream/index.js @@ -43,7 +43,7 @@ checkFFmpeg().then((ffmpegPath) => { return [ "-fflags", "+nobuffer+flush_packets", "-flags", "low_delay", - "-rtbufsize", "4096", + "-rtbufsize", "2048", "-probesize", "128", ...inputArgs, diff --git a/server/tunnel.js b/server/tunnel.js index 5550ebc..654315c 100644 --- a/server/tunnel.js +++ b/server/tunnel.js @@ -100,4 +100,4 @@ httpPassword = "<%= cfg.httpPassword %>" <% } %> `; -module.exports = { connect, download}; \ No newline at end of file +module.exports = { connect, download }; \ No newline at end of file diff --git a/views/403.ejs b/views/403.ejs index b727776..29aeecb 100644 --- a/views/403.ejs +++ b/views/403.ejs @@ -15,7 +15,7 @@
-