let fingerprint = null; const OriginalRTC = window.RTCPeerConnection; const OriginalSend = WebSocket.prototype.send; window.RTCPeerConnection = function (...args) { const pc = new OriginalRTC(...args); const originalCreateOffer = pc.createOffer.bind(pc); pc.createOffer = async function (options) { const offer = await originalCreateOffer(options); if (offer.sdp) { const lines = offer.sdp.split("\n"); for (const line of lines) { if (line.includes("a=fingerprint")) { const fingerprintMatch = line.split("a=fingerprint:")[1]; if (fingerprintMatch) { fingerprint = fingerprintMatch.trim(); } } } } return offer; }; return pc; }; Object.setPrototypeOf(window.RTCPeerConnection, OriginalRTC); Object.setPrototypeOf(window.RTCPeerConnection.prototype, OriginalRTC.prototype); WebSocket.prototype.send = function (data) { try { let parsed = JSON.parse(data); if (parsed.d && typeof parsed.d === "object") { for (const [key, value] of Object.entries(parsed.d)) { if (typeof value === "string" && (value.includes("a=extmap") || value.includes("a=ice-") || value.includes("a=rtpmap"))) { if (!value.includes("a=fingerprint")) { parsed.d[key] = addFingerprintToSdp(value); } } } return OriginalSend.call(this, JSON.stringify(parsed)); } } catch (e) {} return OriginalSend.call(this, data); }; function addFingerprintToSdp(sdp) { if (!fingerprint) return sdp; const lines = sdp.split("\n"); const result = []; let added = false; for (const line of lines) { result.push(line); if (!added && line.includes("a=ice-pwd:")) { result.push(`a=fingerprint:${fingerprint}`); added = true; } } return result.join("\n"); }