Created
January 20, 2024 19:26
-
-
Save LucienHH/dab431394dabc38026ee1dd81cd0cdbc to your computer and use it in GitHub Desktop.
Standard peer-to-peer WebRTC connection via Minecraft Bedrock's signalling channel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const WebSocket = require('ws'); | |
const { RTCPeerConnection } = require('werift'); | |
const token = "" | |
const networkId = ""; | |
const randomID = () => Math.floor(Math.random() * 10000000000000000000) | |
const sessionId = randomID() | |
const offerId = randomID() | |
const main = async () => { | |
const ws = new WebSocket('wss://signal.franchise.minecraft-services.net/ws/v1.0/signaling/9806856835729287287', { | |
headers: { Authorization: token } | |
}); | |
let resolve; | |
const promise = new Promise((res) => { | |
resolve = res; | |
}); | |
ws.on('message', (data) => { | |
const message = JSON.parse(String(data)); | |
switch (message.Type) { | |
case 1: { | |
const [type, id, ...rest] = message.Message.split(' '); | |
if (type === 'CONNECTRESPONSE') { | |
console.log(`Client <- Peer SDP answer`); | |
peer.setRemoteDescription({ type: 'answer', sdp: rest.join(' ') }) | |
} | |
if (type === 'CANDIDATEADD') { | |
console.log(`Client <- Peer ICE candidate: ${rest.join(' ')}`); | |
peer.addIceCandidate({ candidate: rest.join(' ') }) | |
.catch((error) => console.error('Error adding ICE candidate:', error)); | |
} | |
break; | |
} | |
case 2: { | |
const payload = JSON.parse(message.Message); | |
resolve(payload); | |
break; | |
} | |
} | |
}); | |
const data = await promise; | |
const peer = new RTCPeerConnection({ | |
iceServers: [ | |
{ | |
urls: 'stun:relay.communication.microsoft.com:3478', | |
credential: data.Password, | |
username: data.Username | |
}, | |
{ | |
urls: 'turn:relay.communication.microsoft.com:3478', | |
credential: data.Password, | |
username: data.Username | |
}, | |
] | |
}); | |
peer.createDataChannel('test') | |
peer.onnegotiationneeded = async () => { | |
const offer = await peer.createOffer() | |
const pattern = /o=- \d+ 0 IN IP4 0\.0\.0\.0/; | |
const newOLine = `o=- ${offerId} 2 IN IP4 127.0.0.1`; | |
offer.sdp = offer.sdp.replace(pattern, newOLine); | |
console.log(`Client -> Peer SDP offer`); | |
await peer.setLocalDescription(offer) | |
const message = `{"Message": "CONNECTREQUEST ${sessionId} ${offer.sdp}","To":"${networkId}","Type":1}` | |
ws.send(message) | |
} | |
peer.onicecandidate = function (evt) { | |
if (evt.candidate) { | |
console.log(`Client -> Peer ICE candidate: ${evt.candidate.candidate}`); | |
const message = `{"Message":"CANDIDATEADD ${sessionId} ${evt.candidate.candidate}","To":${networkId},"Type":1}` | |
ws.send(message) | |
} | |
}; | |
}; | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment