diff --git a/src/services/wsService.ts b/src/services/wsService.ts index 752c74b7..21244273 100644 --- a/src/services/wsService.ts +++ b/src/services/wsService.ts @@ -86,6 +86,7 @@ interface IWsMsgToClient { nonce_updated?: boolean; update_inventory?: boolean; logged_out?: boolean; + have_game_ws?: boolean; // to game sync_inventory?: boolean; @@ -137,7 +138,8 @@ const wsOnConnect = (ws: WebSocket, req: http.IncomingMessage): void => { id: account.id, DisplayName: account.DisplayName, Nonce: account.Nonce - } + }, + have_game_ws: haveGameWs(account.id) } satisfies IWsMsgToClient) ); } else { @@ -160,6 +162,7 @@ const wsOnConnect = (ws: WebSocket, req: http.IncomingMessage): void => { if (account) { (ws as IWsCustomData).accountId = account.id; logger.debug(`got bootstrapper connection for ${account.id}`); + sendWsBroadcastToWebui({ have_game_ws: true }, account.id); } } } @@ -184,11 +187,15 @@ const wsOnConnect = (ws: WebSocket, req: http.IncomingMessage): void => { ws.on("close", async () => { if ((ws as IWsCustomData).isGame && (ws as IWsCustomData).accountId) { logger.debug(`lost bootstrapper connection for ${(ws as IWsCustomData).accountId}`); - const account = await Account.findOne({ _id: (ws as IWsCustomData).accountId }); - if (account?.Nonce) { - account.Dropped = true; - await account.save(); - } + sendWsBroadcastToWebui({ have_game_ws: false }, (ws as IWsCustomData).accountId); + await Account.updateOne( + { + _id: (ws as IWsCustomData).accountId + }, + { + Dropped: true + } + ); } }); }; @@ -206,6 +213,16 @@ const forEachClient = (cb: (client: IWsCustomData) => void): void => { } }; +export const haveGameWs = (accountId: string): boolean => { + let ret = false; + forEachClient(client => { + if (client.isGame && client.accountId == accountId) { + ret = true; + } + }); + return ret; +}; + export const sendWsBroadcast = (data: IWsMsgToClient): void => { const msg = JSON.stringify(data); forEachClient(client => { @@ -231,7 +248,7 @@ export const sendWsBroadcastToGame = (accountId: string, data: IWsMsgToClient): }); }; -export const sendWsBroadcastEx = (data: IWsMsgToClient, accountId: string | undefined, excludeWsid: number): void => { +export const sendWsBroadcastEx = (data: IWsMsgToClient, accountId?: string, excludeWsid?: number): void => { const msg = JSON.stringify(data); forEachClient(client => { if ((!accountId || client.accountId == accountId) && client.id != excludeWsid) { @@ -240,11 +257,7 @@ export const sendWsBroadcastEx = (data: IWsMsgToClient, accountId: string | unde }); }; -export const sendWsBroadcastToWebui = ( - data: IWsMsgToClient, - accountId: string | undefined, - excludeWsid: number -): void => { +export const sendWsBroadcastToWebui = (data: IWsMsgToClient, accountId?: string, excludeWsid?: number): void => { const msg = JSON.stringify(data); forEachClient(client => { if (!client.isGame && (!accountId || client.accountId == accountId) && client.id != excludeWsid) { @@ -272,9 +285,10 @@ export const handleNonceInvalidation = (accountId: string): void => { forEachClient(client => { if (client.accountId == accountId) { if (client.isGame) { + client.accountId = undefined; // prevent processing of the close event client.close(); } else { - client.send(JSON.stringify({ nonce_updated: true } satisfies IWsMsgToClient)); + client.send(JSON.stringify({ nonce_updated: true, have_game_ws: false } satisfies IWsMsgToClient)); } } });