Peercord/Peercord Source/src/p2p/handlers.js
0% [█ █ █ █ █ █ █ █ █ █] 100% 29e61f07f2 Full source
2026-06-14 21:28:04 -05:00

112 lines
3.9 KiB
JavaScript

const b4a = window.require('b4a');
export async function handleData(network, peerKey, data, conn) {
try {
const parsed = JSON.parse(b4a.toString(data));
switch (parsed.type) {
case 'identity':
await handleIdentity(network, peerKey, parsed);
break;
case 'whois':
handleWhois(network, parsed, conn);
break;
case 'whois_reply':
handleWhoisReply(network, parsed);
break;
case 'ephemeral':
handleEphemeral(network, peerKey, parsed);
break;
default:
// Could be a standard message core, which is handled by replication, not this handler.
}
} catch (err) {
// Likely binary data from core replication, ignore.
}
}
async function handleIdentity(network, peerKey, parsed) {
const peerInfo = network.peers.get(peerKey);
if (!peerInfo) return;
peerInfo.displayName = parsed.displayName;
peerInfo.username = parsed.username;
peerInfo.avatar = parsed.avatar;
peerInfo.coreKey = parsed.coreKey;
const profileObj = { displayName: parsed.displayName, username: parsed.username, avatar: parsed.avatar };
network.knownProfiles.set(peerKey, profileObj);
if (network.profilesDb) await network.profilesDb.put(peerKey, profileObj);
if (network.coresDb && parsed.coreKey) await network.coresDb.put(peerKey, parsed.coreKey);
network._emitKnownProfiles();
if (parsed.username) {
const uname = parsed.username.toLowerCase();
network.userDirectory.set(uname, { pubKey: peerKey, profile: parsed });
network.dirDb.put(uname, { pubKey: peerKey, profile: parsed });
network._checkPendingRequests(uname, peerKey, parsed);
}
if (network.dms[peerKey]) {
network.dms[peerKey].profile = profileObj;
await network.db.put('dm:' + peerKey, network.dms[peerKey]);
if (network.onDMsUpdate) network.onDMsUpdate({ ...network.dms });
}
if (network.onPeerUpdate) network.onPeerUpdate(network.getPeerList());
network._emitMessages();
await network.trackPeerCore(parsed.coreKey);
}
function handleWhois(network, parsed, conn) {
const uname = parsed.username;
if (network.userDirectory.has(uname)) {
const cached = network.userDirectory.get(uname);
const reply = b4a.from(JSON.stringify({ type: 'whois_reply', queryId: parsed.queryId, username: uname, pubKey: cached.pubKey, profile: cached.profile }));
conn.write(reply);
}
}
function handleWhoisReply(network, parsed) {
const cb = network.pendingWhois.get(parsed.queryId);
if (cb) cb({ pubKey: parsed.pubKey, profile: parsed.profile });
network.userDirectory.set(parsed.username, { pubKey: parsed.pubKey, profile: parsed.profile });
network.dirDb.put(parsed.username, { pubKey: parsed.pubKey, profile: parsed.profile });
network._checkPendingRequests(parsed.username, parsed.pubKey, parsed.profile);
}
function handleEphemeral(network, peerKey, parsed) {
const { payload } = parsed;
if (!payload) return;
if (payload.type === 'offline') {
const peerInfo = network.peers.get(peerKey);
if (peerInfo) {
network.peers.delete(peerKey);
try { peerInfo.conn.destroy(); } catch (e) {}
if (network.onPeerUpdate) network.onPeerUpdate(network.getPeerList());
}
}
if (payload.type.startsWith('webrtc-') || payload.type === 'voice_activity' || payload.type.startsWith('vc-')) {
for (const fn of network.webrtcListeners) fn(peerKey, payload);
}
if (payload.type === 'transfer_progress') {
const current = network.transfers[payload.id] || { progress: 0, speed: 0 };
if (payload.progress >= current.progress || payload.progress === 1) {
network.transfers[payload.id] = {
...current,
progress: payload.progress,
speed: payload.speed,
state: payload.progress >= 1 ? 'completed' : 'uploading'
};
if (network.onTransfersUpdate) network.onTransfersUpdate(network.transfers);
}
}
if (network.onEphemeral) network.onEphemeral(peerKey, payload);
}