mirror of
https://github.com/YuzuZensai/Discord-Presence-Relay.git
synced 2026-09-13 17:01:36 +00:00
🐛 fix: instantly clear presence on disable
This commit is contained in:
@@ -29,6 +29,15 @@ export class MirrorConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends a final frame and closes the connection once it has been flushed. */
|
||||||
|
sendActivityAndClose(payload: Buffer): void {
|
||||||
|
if (this.sock.writable) {
|
||||||
|
this.sock.end(encodeFrame(OP_FRAME, payload))
|
||||||
|
} else {
|
||||||
|
this.sock.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
this.sock.destroy()
|
this.sock.destroy()
|
||||||
}
|
}
|
||||||
|
|||||||
+55
-16
@@ -1,3 +1,4 @@
|
|||||||
|
import { randomUUID } from 'crypto'
|
||||||
import { EventEmitter } from 'events'
|
import { EventEmitter } from 'events'
|
||||||
import * as net from 'net'
|
import * as net from 'net'
|
||||||
import { encodeFrame, Frame, FrameReader, OP_HANDSHAKE, parseFramePayload } from './ipc-protocol'
|
import { encodeFrame, Frame, FrameReader, OP_HANDSHAKE, parseFramePayload } from './ipc-protocol'
|
||||||
@@ -123,6 +124,8 @@ export class RpcRelay extends EventEmitter {
|
|||||||
private running = false
|
private running = false
|
||||||
private lastError: string | null = null
|
private lastError: string | null = null
|
||||||
private restarting = false
|
private restarting = false
|
||||||
|
private mirrors = new Map<number, MirrorConnection>()
|
||||||
|
private lastActivityPid = new Map<number, number>()
|
||||||
|
|
||||||
getStatus(): RelayStatus {
|
getStatus(): RelayStatus {
|
||||||
const instances: RelayInstance[] = this.claimed.map(({ index, path: socketPath }, i) => ({
|
const instances: RelayInstance[] = this.claimed.map(({ index, path: socketPath }, i) => ({
|
||||||
@@ -150,6 +153,7 @@ export class RpcRelay extends EventEmitter {
|
|||||||
this.disabledMirrors.delete(index)
|
this.disabledMirrors.delete(index)
|
||||||
} else {
|
} else {
|
||||||
this.disabledMirrors.add(index)
|
this.disabledMirrors.add(index)
|
||||||
|
this.clearMirrorActivity(index)
|
||||||
}
|
}
|
||||||
this.emitStatus()
|
this.emitStatus()
|
||||||
return this.getStatus()
|
return this.getStatus()
|
||||||
@@ -219,6 +223,10 @@ export class RpcRelay extends EventEmitter {
|
|||||||
platform.removeFakeSocket(platform.fakeSocketPath())
|
platform.removeFakeSocket(platform.fakeSocketPath())
|
||||||
for (const claimed of this.claimed) platform.restoreSocket(claimed)
|
for (const claimed of this.claimed) platform.restoreSocket(claimed)
|
||||||
|
|
||||||
|
for (const mirror of this.mirrors.values()) mirror.destroy()
|
||||||
|
this.mirrors.clear()
|
||||||
|
this.lastActivityPid.clear()
|
||||||
|
|
||||||
this.claimed = []
|
this.claimed = []
|
||||||
this.connectedClients.clear()
|
this.connectedClients.clear()
|
||||||
this.emitStatus()
|
this.emitStatus()
|
||||||
@@ -280,13 +288,13 @@ export class RpcRelay extends EventEmitter {
|
|||||||
const primaryReader = new FrameReader()
|
const primaryReader = new FrameReader()
|
||||||
|
|
||||||
let handshakePayload: Buffer | null = null
|
let handshakePayload: Buffer | null = null
|
||||||
const mirrors = new Map<number, MirrorConnection>()
|
|
||||||
|
|
||||||
const cleanup = (): void => {
|
const cleanup = (): void => {
|
||||||
client.destroy()
|
client.destroy()
|
||||||
primary.destroy()
|
primary.destroy()
|
||||||
for (const mirror of mirrors.values()) mirror.destroy()
|
for (const mirror of this.mirrors.values()) mirror.destroy()
|
||||||
mirrors.clear()
|
this.mirrors.clear()
|
||||||
|
this.lastActivityPid.clear()
|
||||||
this.connectedClients.delete(clientId)
|
this.connectedClients.delete(clientId)
|
||||||
this.emitStatus()
|
this.emitStatus()
|
||||||
}
|
}
|
||||||
@@ -309,7 +317,7 @@ export class RpcRelay extends EventEmitter {
|
|||||||
pendingToPrimary.push(encoded)
|
pendingToPrimary.push(encoded)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (handshakePayload) this.mirrorFrame(frame, handshakePayload, mirrors)
|
if (handshakePayload) this.mirrorFrame(frame, handshakePayload)
|
||||||
void this.recordActivity(frame, clientAppId)
|
void this.recordActivity(frame, clientAppId)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -355,28 +363,35 @@ export class RpcRelay extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Forwards the handshake and SET_ACTIVITY frames to every enabled mirror instance. */
|
/** Forwards the handshake and SET_ACTIVITY frames to every enabled mirror instance. */
|
||||||
private mirrorFrame(
|
private mirrorFrame(frame: Frame, handshakePayload: Buffer): void {
|
||||||
frame: Frame,
|
const payload = frame.op !== OP_HANDSHAKE ? parseFramePayload(frame) : null
|
||||||
handshakePayload: Buffer,
|
const isSetActivity = payload?.cmd === 'SET_ACTIVITY'
|
||||||
mirrors: Map<number, MirrorConnection>
|
|
||||||
): void {
|
|
||||||
const isSetActivity =
|
|
||||||
frame.op !== OP_HANDSHAKE && parseFramePayload(frame)?.cmd === 'SET_ACTIVITY'
|
|
||||||
if (frame.op !== OP_HANDSHAKE && !isSetActivity) return
|
if (frame.op !== OP_HANDSHAKE && !isSetActivity) return
|
||||||
|
|
||||||
|
if (isSetActivity) {
|
||||||
|
const pid = (payload!.args as { pid?: number } | undefined)?.pid
|
||||||
|
if (typeof pid === 'number') {
|
||||||
|
for (let i = 1; i < this.claimed.length; i++) {
|
||||||
|
this.lastActivityPid.set(this.claimed[i].index, pid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let i = 1; i < this.claimed.length; i++) {
|
for (let i = 1; i < this.claimed.length; i++) {
|
||||||
const { index, path: mirrorPath } = this.claimed[i]
|
const { index, path: mirrorPath } = this.claimed[i]
|
||||||
|
|
||||||
if (this.disabledMirrors.has(index)) {
|
if (this.disabledMirrors.has(index)) {
|
||||||
mirrors.get(i)?.destroy()
|
this.mirrors.get(index)?.destroy()
|
||||||
mirrors.delete(i)
|
this.mirrors.delete(index)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
let mirror = mirrors.get(i)
|
let mirror = this.mirrors.get(index)
|
||||||
if (!mirror) {
|
if (!mirror) {
|
||||||
mirror = new MirrorConnection(mirrorPath, handshakePayload, () => mirrors.delete(i))
|
mirror = new MirrorConnection(mirrorPath, handshakePayload, () =>
|
||||||
mirrors.set(i, mirror)
|
this.mirrors.delete(index)
|
||||||
|
)
|
||||||
|
this.mirrors.set(index, mirror)
|
||||||
if (frame.op === OP_HANDSHAKE) continue // handshake already sent on connect
|
if (frame.op === OP_HANDSHAKE) continue // handshake already sent on connect
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,6 +399,30 @@ export class RpcRelay extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Sends a SET_ACTIVITY frame clearing the presence on a mirror, then disconnects it. */
|
||||||
|
private clearMirrorActivity(index: number): void {
|
||||||
|
const mirror = this.mirrors.get(index)
|
||||||
|
if (!mirror) return
|
||||||
|
|
||||||
|
const pid = this.lastActivityPid.get(index)
|
||||||
|
if (pid !== undefined) {
|
||||||
|
const clearPayload = Buffer.from(
|
||||||
|
JSON.stringify({
|
||||||
|
cmd: 'SET_ACTIVITY',
|
||||||
|
args: { pid, activity: null },
|
||||||
|
nonce: randomUUID()
|
||||||
|
}),
|
||||||
|
'utf8'
|
||||||
|
)
|
||||||
|
mirror.sendActivityAndClose(clearPayload)
|
||||||
|
} else {
|
||||||
|
mirror.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.mirrors.delete(index)
|
||||||
|
this.lastActivityPid.delete(index)
|
||||||
|
}
|
||||||
|
|
||||||
private async recordActivity(frame: Frame, appId: string | null): Promise<void> {
|
private async recordActivity(frame: Frame, appId: string | null): Promise<void> {
|
||||||
if (frame.op === OP_HANDSHAKE) return
|
if (frame.op === OP_HANDSHAKE) return
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user