mirror of
https://github.com/KubaPro010/fm-dx-webserver.git
synced 2026-07-29 16:29:19 +02:00
ugh! improvements AGAIN?
This commit is contained in:
@@ -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);
|
||||
|
||||
+15
-25
@@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+4
-9
@@ -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++;
|
||||
|
||||
+9
-14
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
],
|
||||
|
||||
@@ -42,7 +42,7 @@ let serverConfig = {
|
||||
xdrdPassword: ""
|
||||
},
|
||||
audio: {
|
||||
audioDevice: "Microphone (High Definition Audio Device)",
|
||||
audioDevice: null,
|
||||
audioChannels: 2,
|
||||
audioBitrate: "128k",
|
||||
startupVolume: "1"
|
||||
|
||||
@@ -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`);
|
||||
|
||||
@@ -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: ''
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
+1
-3
@@ -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,
|
||||
|
||||
+8
-10
@@ -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 };
|
||||
module.exports = startServer;
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user