186 lines
7.6 KiB
TypeScript
186 lines
7.6 KiB
TypeScript
import {JsonManager} from "./json_manager";
|
|
import {UdpClient} from "../network/udp/udp_client";
|
|
import {parentPort} from "worker_threads";
|
|
import {TcpCommunicator} from "./tcp_communicator";
|
|
import {operationCodes} from "../network/operation_codes";
|
|
import {ParsedMessage} from "../network/message_handler";
|
|
|
|
export class NetworkScanner {
|
|
private applicationInfo: JsonManager;
|
|
private userConfig: JsonManager;
|
|
private readonly udpPort: number;
|
|
private readonly tcpPort: number;
|
|
private readonly okPage: string;
|
|
private readonly errorPage: string;
|
|
private readonly databaseResetPage: string;
|
|
private appStarted = false;
|
|
private intervalIds: NodeJS.Timeout[] = [];
|
|
|
|
// Flags to prevent overlapping executions
|
|
private ucCheckBusy = false;
|
|
private ipLookupBusy = false;
|
|
private sendLoginBusy = false;
|
|
|
|
constructor(applicationInfoPath: string, userConfigPath: string, udpPort: number, tcpPort: number, okPage: string, errorPage: string, databaseResetPage: string) {
|
|
this.applicationInfo = new JsonManager(applicationInfoPath);
|
|
this.userConfig = new JsonManager(userConfigPath);
|
|
this.udpPort = udpPort;
|
|
this.tcpPort = tcpPort;
|
|
this.okPage = okPage;
|
|
this.errorPage = errorPage;
|
|
this.databaseResetPage = databaseResetPage;
|
|
|
|
// Start tasks
|
|
this.startUCCheck();
|
|
this.startUserIPLookup();
|
|
this.sendLoginRequest();
|
|
}
|
|
|
|
// Log helper function for consistent logging format
|
|
private log(message: string, level: 'log' | 'error' = 'log', methodName: string = ''): void {
|
|
const prefix = `[NetworkScanner${methodName ? `.${methodName}` : ''}]`;
|
|
if (level === 'error') {
|
|
console.error(`${prefix} ${message}`);
|
|
} else {
|
|
console.log(`${prefix} ${message}`);
|
|
}
|
|
}
|
|
|
|
// UC Check Task
|
|
private startUCCheck(interval: number = 5000): void {
|
|
const intervalId = setInterval(async () => {
|
|
if (this.ucCheckBusy) return;
|
|
this.ucCheckBusy = true;
|
|
|
|
try {
|
|
this.log('UC Check running...', 'log', 'startUCCheck');
|
|
const udpClient = new UdpClient(this.udpPort);
|
|
const aliveClients = await udpClient.getAliveClients();
|
|
const storedIp = await this.applicationInfo.readValue('serverIp');
|
|
const foundClient = aliveClients.length > 0;
|
|
|
|
if (foundClient) {
|
|
const ipAddress = aliveClients[0]; // Use the first alive client
|
|
|
|
if (!storedIp || storedIp !== ipAddress) {
|
|
await this.applicationInfo.writeValue('serverIp', ipAddress);
|
|
if (!this.appStarted) {
|
|
parentPort?.postMessage({ type: 'changeContent', page: this.okPage });
|
|
}
|
|
this.appStarted = true;
|
|
} else if (!this.appStarted) {
|
|
parentPort?.postMessage({ type: 'changeContent', page: this.okPage });
|
|
this.appStarted = true;
|
|
}
|
|
} else {
|
|
parentPort?.postMessage({ type: 'changeContent', page: this.errorPage });
|
|
}
|
|
} catch (err) {
|
|
this.log(`Error checking UC: ${err}`, 'error', 'startUCCheck');
|
|
parentPort?.postMessage({ type: 'changeContent', page: this.errorPage });
|
|
} finally {
|
|
this.ucCheckBusy = false;
|
|
}
|
|
}, interval);
|
|
|
|
this.intervalIds.push(intervalId);
|
|
}
|
|
|
|
// IP Lookup Task
|
|
private startUserIPLookup(interval: number = 10000): void {
|
|
const intervalId = setInterval(async () => {
|
|
if (this.ipLookupBusy) return;
|
|
this.ipLookupBusy = true;
|
|
|
|
try {
|
|
this.log('IP Lookup running...', 'log', 'startUserIPLookup');
|
|
const serverIp = await this.applicationInfo.readValue('serverIp');
|
|
const udpClient = new UdpClient(this.udpPort);
|
|
const activeIPs = await udpClient.getAliveClients();
|
|
const filteredIPs = activeIPs.filter(ip => ip !== serverIp);
|
|
|
|
// Save the filtered IPs to 'users_ip'
|
|
await this.applicationInfo.writeValue('users_ip', filteredIPs);
|
|
} catch (err) {
|
|
this.log(`Error during user IP lookup: ${err}`, 'error', 'startUserIPLookup');
|
|
} finally {
|
|
this.ipLookupBusy = false;
|
|
}
|
|
}, interval);
|
|
|
|
this.intervalIds.push(intervalId);
|
|
}
|
|
|
|
// Login Request Task
|
|
private sendLoginRequest(interval: number = 5000): void {
|
|
const intervalId = setInterval(async () => {
|
|
if (this.sendLoginBusy || this.appStarted) return;
|
|
this.sendLoginBusy = true;
|
|
|
|
try {
|
|
const userInfo = await this.userConfig.readValue('user_info');
|
|
if (!userInfo || !userInfo.email || !userInfo.password) {
|
|
this.log("Email or password not found in user config.", 'error', 'sendLoginRequest');
|
|
return;
|
|
}
|
|
|
|
const app_type = await this.userConfig.readValue('app_type');
|
|
const email = userInfo.email;
|
|
const password = userInfo.password;
|
|
const serverIp = await this.applicationInfo.readValue('serverIp');
|
|
|
|
if (!serverIp) {
|
|
this.log("Server IP not found in application info.", 'error', 'sendLoginRequest');
|
|
return;
|
|
}
|
|
|
|
const tcpCommunicator = new TcpCommunicator(serverIp, this.tcpPort);
|
|
|
|
if (!await tcpCommunicator.connect()) {
|
|
this.log("Failed to connect to the server.", 'error', 'sendLoginRequest');
|
|
return;
|
|
}
|
|
|
|
const metaInfo = { email, password, app_type };
|
|
if (!await tcpCommunicator.sendMessage(operationCodes.LOGIN, metaInfo)) {
|
|
this.log("Failed to send login request.", 'error', 'sendLoginRequest');
|
|
await tcpCommunicator.disconnect();
|
|
return;
|
|
}
|
|
|
|
const response = await this.waitForResponse(tcpCommunicator);
|
|
if (response?.operationCode !== operationCodes.OK) {
|
|
await this.userConfig.resetFile();
|
|
await this.userConfig.writeValue('app_type', app_type);
|
|
parentPort?.postMessage({ type: 'changeContent', page: this.databaseResetPage });
|
|
}
|
|
} catch (err) {
|
|
this.log(`Error during login request: ${err}`, 'error', 'sendLoginRequest');
|
|
} finally {
|
|
this.sendLoginBusy = false;
|
|
}
|
|
}, interval);
|
|
|
|
this.intervalIds.push(intervalId);
|
|
}
|
|
|
|
// Helper function to wait for a response from the TCP communicator
|
|
private async waitForResponse(tcpCommunicator: TcpCommunicator): Promise<ParsedMessage | null> {
|
|
return new Promise((resolve) => {
|
|
const checkInterval = setInterval(() => {
|
|
if (tcpCommunicator.hasResponseArrived()) {
|
|
clearInterval(checkInterval);
|
|
resolve(tcpCommunicator.getLastResult());
|
|
}
|
|
}, 100);
|
|
});
|
|
}
|
|
|
|
// Method to stop all intervals (for cleanup if needed)
|
|
public stopAllIntervals(): void {
|
|
for (const id of this.intervalIds) {
|
|
clearInterval(id);
|
|
}
|
|
this.log("All intervals have been stopped.", 'log', 'stopAllIntervals');
|
|
}
|
|
} |