diff --git a/server/datahandler.js b/server/datahandler.js index 8dbad07..9ebfa98 100644 --- a/server/datahandler.js +++ b/server/datahandler.js @@ -1,5 +1,5 @@ /* Libraries / Imports */ -const { send_xdr_online } = require('./xdr_server'); +const { send_xdr_online, send_to_xdr } = require('./xdr_server'); const RDSDecoder = require("./rds.js"); const { serverConfig } = require('./server_config'); @@ -85,6 +85,8 @@ function rdsReset() { } function handleData(wss, receivedData, rdsWss) { + send_to_xdr(receivedData); + // Retrieve the last update time for this client const currentTime = Date.now(); @@ -117,9 +119,7 @@ function handleData(wss, receivedData, rdsWss) { dataToSend.pi = '?'; dataToSend.txInfo.reg = false; - rdsWss.clients.forEach((client) => { - client.send("G:\r\nRESET-------\r\n\r\n"); - }); + rdsWss.clients.forEach((client) => client.send("G:\r\nRESET-------\r\n\r\n")); } break; case receivedLine.startsWith('Z'): // Antenna @@ -228,9 +228,7 @@ function handleData(wss, receivedData, rdsWss) { }; } }) - .catch((error) => { - console.log("Error fetching Tx info:", error); - }); + .catch((error) => console.log("Error fetching Tx info:", error)); // Send the updated data to the client const dataToSendJSON = JSON.stringify(dataToSend); diff --git a/server/helpers.js b/server/helpers.js index 144062e..21637a2 100644 --- a/server/helpers.js +++ b/server/helpers.js @@ -7,7 +7,6 @@ const dataHandler = require('./datahandler'); const storage = require('./storage'); const consoleCmd = require('./console'); const { serverConfig, configSave } = require('./server_config'); -const { send_to_xdr } = require("./xdr_server") let geoip = null; try { @@ -139,9 +138,7 @@ function handleConnect(clientIp, currentUsers, ws, callback) { regionName: geo.region, }; } - } else if (!geoip) { - consoleCmd.logWarn('geoip-lite is not installed; location will be Unknown.'); - } + } else if (!geoip) consoleCmd.logWarn('geoip-lite is not installed; location will be Unknown.'); const inFlightPromise = fetchIpWhoisInfo(clientIp) .then((whoisInfo) => { @@ -166,12 +163,10 @@ function fetchBannedAS(callback) { const now = Date.now(); if (bannedASCache.data && now - bannedASCache.timestamp < 10 * 60 * 1000) return callback(bannedASCache.data); - const req = https.get("https://fmdx.org/banned_as.json", { family: 4 }, (banResponse) => { + const req = https.get("https://flerken.zapto.org:5000/banned_as.json", { family: 4 }, (banResponse) => { let banData = ""; - banResponse.on("data", (chunk) => { - banData += chunk; - }); + banResponse.on("data", (chunk) => banData += chunk); banResponse.on("end", () => { try { @@ -185,8 +180,8 @@ function fetchBannedAS(callback) { }); }); - // Set timeout for the request (5 seconds) - req.setTimeout(5000, () => { + // Set timeout for the request (3 seconds) + req.setTimeout(3000, () => { console.error("Error: Request timed out while fetching banned AS list."); req.abort(); callback([]); // Default to allowing user @@ -232,12 +227,9 @@ function processConnection(clientIp, locationInfo, currentUsers, ws, callback) { const userLocationForLog = locationInfo?.isp ? `${userLocation} (${locationInfo.isp})` : userLocation; storage.connectedUsers.push({ - ip: clientIp, - location: userLocation, - isp: locationInfo?.isp, - as: locationInfo?.as, - time: connectionTime, - instance: ws, + ip: clientIp, location: userLocation, + isp: locationInfo?.isp, as: locationInfo?.as, + time: connectionTime, instance: ws, }); consoleCmd.logInfo(`Web client \x1b[32mconnected\x1b[0m (${clientIp}) \x1b[90m[${currentUsers}]\x1b[0m Location: ${userLocationForLog}`); @@ -259,7 +251,10 @@ function formatUptime(uptimeInSeconds) { let incompleteDataBuffer = ''; -function resolveDataBuffer(data, wss, rdsWss) { +function resolveDataBuffer(data) { + const wss = storage.websocket_delegation.get("/text"); // Genius + const rdsWss = storage.websocket_delegation.get("/rds"); + var receivedData = incompleteDataBuffer + data.toString(); const isIncomplete = (receivedData.slice(-1) != '\n'); @@ -274,10 +269,7 @@ function resolveDataBuffer(data, wss, rdsWss) { } } else incompleteDataBuffer = ''; - if (receivedData.length) { - dataHandler.handleData(wss, receivedData, rdsWss); - send_to_xdr(receivedData); - } + if (receivedData.length) dataHandler.handleData(wss, receivedData, rdsWss); } function kickClient(ipAddress) { @@ -311,12 +303,10 @@ function checkLatency(host, port = 80, timeout = 2000) { socket.on("timeout", () => { socket.destroy(); - resolve(null); // timed out + resolve(null); // timed out (yeah thanks, didn't see that but that comment had changed how i look on the world) }); - socket.on("error", () => { - resolve(null); // offline - }); + socket.on("error", () => resolve(null)); }); } diff --git a/server/index.js b/server/index.js index 0116b28..b62dfee 100644 --- a/server/index.js +++ b/server/index.js @@ -5,7 +5,7 @@ const dataHandler = require('./datahandler'); const { logError, logInfo, logWarn } = require('./console'); const { serverConfig, configExists } = require('./server_config'); const pluginsApi = require('./plugins_api'); -const { startServer, wss, rdsWss } = require("./web"); +const startServer = require("./web"); const client = new (require('net')).Socket(); @@ -104,13 +104,8 @@ function connectToSerial() { : serialport.write('Y100\n'); }, 6000); - serialport.on('data', (data) => { - helpers.resolveDataBuffer(data, wss, rdsWss); - }); - - serialport.on('error', (error) => { - logError(error.message); - }); + serialport.on('data', (data) => helpers.resolveDataBuffer(data)); + serialport.on('error', (error) => logError(error.message)); }); // Handle port closure @@ -150,7 +145,7 @@ function connectToXdrd() { client.on('data', (data) => { const { xdrd } = serverConfig; - helpers.resolveDataBuffer(data, wss, rdsWss); + helpers.resolveDataBuffer(data); if (authFlags.authMsg == true && authFlags.messageCount > 1) return; authFlags.messageCount++; diff --git a/server/plugins.js b/server/plugins.js index 1acbdbc..b412d36 100644 --- a/server/plugins.js +++ b/server/plugins.js @@ -71,22 +71,17 @@ function collectPluginConfigs() { const webJsPluginsDir = path.join(__dirname, '../web/js/plugins'); if (!fs.existsSync(webJsPluginsDir)) fs.mkdirSync(webJsPluginsDir, { recursive: true }); -// Main function to create symlinks/junctions for plugins -function createLinks() { - if (process.platform === 'win32') { - 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 }); - fs.symlinkSync(pluginsDir, destinationPluginsDir, 'junction'); - } catch (err) { - console.error(`Error creating junction at ${destinationPluginsDir}: ${err.message}`); - } + // On Windows, create a junction + try { + if (fs.existsSync(destinationPluginsDir)) fs.rmSync(destinationPluginsDir, { recursive: true }); + fs.symlinkSync(pluginsDir, destinationPluginsDir, 'junction'); + } catch (err) { + console.error(`Error creating junction at ${destinationPluginsDir}: ${err.message}`); } } -// the usage example comment that was here got me so laughing, that i don't know about all of this -createLinks(); module.exports = collectPluginConfigs(); diff --git a/server/plugins_api.js b/server/plugins_api.js index 23a406c..6624bdb 100644 --- a/server/plugins_api.js +++ b/server/plugins_api.js @@ -76,7 +76,6 @@ async function sendPrivilegedCommand(command, isPluginInternal = false) { if (isPluginInternal) { output.write(`${command}\n`); - //logInfo(`[Privileged Plugin] Command sent: ${command}`); // Debug return true; } diff --git a/server/rds_country.js b/server/rds_country.js index a93077c..d1fc658 100644 --- a/server/rds_country.js +++ b/server/rds_country.js @@ -218,7 +218,7 @@ var countries = [ "Vietnam", "Kiribati", "North Korea", - "Brazil/Equator" + "Brazil/Equador" ] var iso = [ @@ -444,8 +444,6 @@ var iso = [ "--" ] -// RDS ECC Lookup Tables - Converted from C to JavaScript - const rdsEccA0A6Lut = [ // A0 [ @@ -461,7 +459,7 @@ const rdsEccA0A6Lut = [ ], // A2 [ - "Anguilla", "Antigua and Barbuda", "Brazil/Equator", "Falkland Islands", "Barbados", + "Anguilla", "Antigua and Barbuda", "Brazil/Equador", "Falkland Islands", "Barbados", "Belize", "Cayman Islands", "Costa Rica", "Cuba", "Argentina", "Brazil", "Brazil/Bermuda", "Brazil/AN", "Guadeloupe", "Bahamas" ], diff --git a/server/server_config.js b/server/server_config.js index 69fbdb3..564c9d9 100644 --- a/server/server_config.js +++ b/server/server_config.js @@ -42,7 +42,7 @@ let serverConfig = { xdrdPassword: "" }, audio: { - audioDevice: "Microphone (High Definition Audio Device)", + audioDevice: null, audioChannels: 2, audioBitrate: "128k", startupVolume: "1" diff --git a/server/stream/index.js b/server/stream/index.js index d549800..b489f0b 100644 --- a/server/stream/index.js +++ b/server/stream/index.js @@ -3,7 +3,7 @@ const audio_pipe = new PassThrough(); module.exports = audio_pipe; // Important const { serverConfig, configExists } = require('../server_config'); -if (!configExists()) return; +if (!configExists() || !serverConfig.audio.audioDevice) return; const { spawn } = require('child_process'); const { logDebug, logError, logInfo, logWarn, logFfmpeg } = require('../console'); @@ -20,7 +20,6 @@ function connectMessage(message) { } } - checkFFmpeg().then((ffmpegPath) => { logInfo(`${consoleLogTitle} Using ${ffmpegPath === 'ffmpeg' ? 'system-installed FFmpeg' : 'ffmpeg-static'}`); logInfo(`${consoleLogTitle} Starting audio stream on device: \x1b[35m${serverConfig.audio.audioDevice}\x1b[0m`); diff --git a/server/tuner_profiles.js b/server/tuner_profiles.js index 453afb6..344f044 100644 --- a/server/tuner_profiles.js +++ b/server/tuner_profiles.js @@ -19,8 +19,7 @@ const tunerProfiles = [ { value: 254000, label: '254 kHz' }, { value: 287000, label: '287 kHz' }, { value: 311000, label: '311 kHz' } - ], - details: '' + ], details: '' }, { id: 'xdr', @@ -43,12 +42,11 @@ const tunerProfiles = [ { value: 281000, value2: 13, label: '281 kHz' }, { value: 298000, value2: 14, label: '298 kHz' }, { value: 309000, value2: 15, label: '309 kHz' } - ], - details: '' + ], details: '' }, { id: 'sdr', - label: 'SDR (RTL-SDR / AirSpy)', + label: 'SDR', fmBandwidths: [ { value: 0, label: 'Auto' }, { value: 4000, label: '4 kHz' }, @@ -64,20 +62,18 @@ const tunerProfiles = [ { value: 175000, label: '175 kHz' }, { value: 200000, label: '200 kHz' }, { value: 225000, label: '225 kHz' } - ], - details: '' + ], details: '' }, { id: 'si47xx', - label: 'Si47XX (Si4735 / Si4732)', + label: 'Si47xx (Si4735 / Si4732)', fmBandwidths: [ { value: 0, label: 'Auto' }, { value: 40000, label: '40 kHz' }, { value: 60000, label: '60 kHz' }, { value: 84000, label: '84 kHz' }, { value: 110000, label: '110 kHz' } - ], - details: '' + ], details: '' } ]; diff --git a/server/tunnel.js b/server/tunnel.js index 0688ed0..381730e 100644 --- a/server/tunnel.js +++ b/server/tunnel.js @@ -51,9 +51,7 @@ async function connect() { const cfgPath = path.resolve(librariesDir, 'frpc.toml'); await fs.writeFile(cfgPath, cfg); const child = spawn(frpcPath, ['-c', cfgPath]); - process.on('exit', () => { - child.kill(); - }); + process.on('exit', () => child.kill()); const rl = readline.createInterface({ input: child.stdout, diff --git a/server/web.js b/server/web.js index c8b981b..eff95cc 100644 --- a/server/web.js +++ b/server/web.js @@ -24,10 +24,16 @@ const sessionMiddleware = session({ }); app.use(sessionMiddleware); app.use(bodyParser.json()); +app.set('view engine', 'ejs'); +app.set('views', path.join(__dirname, '../views')); +app.use('/', endpoints); +app.use(express.static(path.join(__dirname, '../web'))); const wss = new WebSocket.Server({ noServer: true }); const rdsWss = new WebSocket.Server({ noServer: true }); const pluginsWss = new WebSocket.Server({ noServer: true, perMessageDeflate: true }); +pluginsApi.registerServerContext({ wss, pluginsWss, httpServer, serverConfig }); + require('./chat'); const tunerLockTracker = new WeakMap(); @@ -294,15 +300,7 @@ 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'))); -pluginsApi.registerServerContext({ wss, pluginsWss, httpServer, serverConfig }); - -const logServerStart = (address) => { - logInfo(`Web server has started on address \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); -}; +const logServerStart = (address) => logInfo(`Web server has started on address \x1b[34mhttp://${address}:${serverConfig.webserver.webserverPort}\x1b[0m.`); const startServer = (address) => { httpServer.listen(serverConfig.webserver.webserverPort, address, () => { @@ -313,4 +311,4 @@ const startServer = (address) => { }); }; -module.exports = { startServer, wss, rdsWss }; \ No newline at end of file +module.exports = startServer; \ No newline at end of file diff --git a/server/xdr_server.js b/server/xdr_server.js index b226cc3..4b32047 100644 --- a/server/xdr_server.js +++ b/server/xdr_server.js @@ -66,9 +66,9 @@ xdr.on('connection', async (ws, request) => { ws.send(`A${initialData.agc}\n`); ws.send(`F${initialData.bw}\n`); ws.send(`W${initialData.bw}\n`); - ws.send(`wL${serverConfig.lockToAdmin ? "1" : "0"}\n`); // Don't know how XDR-GTK will handle this, but lets hope it will be fine - ws.send(`wT${serverConfig.publicTuner ? "0" : "1"}\n`); // Again - ws.send(`OK\n`); // Make sure dumbass clients don't need to wait long for the OK, does the comms really REQUIRE you to start the receiver for you to know you are in? + ws.send(`wL${serverConfig.lockToAdmin ? "1" : "0"}\n`); + ws.send(`wT${serverConfig.publicTuner ? "0" : "1"}\n`); + ws.send(`OK\n`); // Make sure dumbass clients don't need to wait long for the OK, does the protocol really REQUIRE you to start the receiver for you to know you are in? clients.push(ws); ws.on('message', (message) => {