Pairing-Logs in ?debug: _log() in p2p.js, Panel links unten
All checks were successful
Pin to IPFS / pin (push) Successful in 11s
All checks were successful
Pin to IPFS / pin (push) Successful in 11s
This commit is contained in:
parent
f3f43ae68e
commit
becd1593b6
4 changed files with 95 additions and 5 deletions
15
app.js
15
app.js
|
|
@ -281,6 +281,7 @@
|
|||
mesh.playerName = name;
|
||||
mesh.names.set(mesh.myPeerId, name || mesh.myPeerId.slice(0, 8));
|
||||
mesh.onchat = (peerId, text) => addChatMessage(mesh.getPeerName(peerId), text);
|
||||
mesh.onlog = addPairingLog;
|
||||
|
||||
mesh.onpeerconnect = pid => {
|
||||
renderPlayers('host-player-list');
|
||||
|
|
@ -348,7 +349,7 @@
|
|||
mesh.playerName = name;
|
||||
mesh.names.set(mesh.myPeerId, name || mesh.myPeerId.slice(0, 8));
|
||||
mesh.onchat = (peerId, text) => addChatMessage(mesh.getPeerName(peerId), text);
|
||||
show('join');
|
||||
mesh.onlog = addPairingLog;
|
||||
$('join-answer-section').hidden = true;
|
||||
$('join-scan-status').textContent = 'QR-Code scannen...';
|
||||
|
||||
|
|
@ -438,6 +439,18 @@
|
|||
show('start');
|
||||
});
|
||||
|
||||
/* ─── Debug pairing log ─── */
|
||||
const pairingMessages = $('debug-pairing-messages');
|
||||
|
||||
function addPairingLog(msg) {
|
||||
if (!pairingMessages) return;
|
||||
const div = document.createElement('div');
|
||||
const t = new Date().toLocaleTimeString('de-DE', { hour12: false });
|
||||
div.textContent = `[${t}] ${msg}`;
|
||||
pairingMessages.appendChild(div);
|
||||
pairingMessages.scrollTop = pairingMessages.scrollHeight;
|
||||
}
|
||||
|
||||
/* ─── Debug chat ─── */
|
||||
const chatInput = $('debug-chat-text');
|
||||
const chatMessages = $('debug-chat-messages');
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@
|
|||
<button id="debug-chat-send">Senden</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="debug-pairing" class="debug-only">
|
||||
<div id="debug-pairing-header">Pairing-Logs</div>
|
||||
<div id="debug-pairing-messages"></div>
|
||||
</div>
|
||||
<footer>
|
||||
<p>© by neunzig.wtf · commit <a id="commit-hash" href="https://git.ziemlichoptimal.de/90wtf/randomp2p/src/commit/HASH">HASH</a></p>
|
||||
</footer>
|
||||
|
|
|
|||
43
p2p.js
43
p2p.js
|
|
@ -22,8 +22,11 @@ class MeshNet {
|
|||
this.onanswerready = null;
|
||||
this.onreadyupdate = null;
|
||||
this.onchat = null;
|
||||
this.onlog = null;
|
||||
}
|
||||
|
||||
_log(msg) { if (this.onlog) this.onlog(msg); }
|
||||
|
||||
/* ─── Host: room ─── */
|
||||
|
||||
createRoom() {
|
||||
|
|
@ -42,6 +45,7 @@ class MeshNet {
|
|||
peer.on('signal', async signal => {
|
||||
if (signalSent) return;
|
||||
signalSent = true;
|
||||
this._log('SDP-Signal (Offer) empfangen');
|
||||
|
||||
const minSignal = signal.sdp ? { ...signal, sdp: stripSDP(signal.sdp) } : signal;
|
||||
const packed = await pack({ v: 1, id: this.myPeerId, s: minSignal });
|
||||
|
|
@ -49,10 +53,12 @@ class MeshNet {
|
|||
this._fullSDPData = this._currentQRData;
|
||||
|
||||
if (this.onqrupdate) this.onqrupdate(this._currentQRData);
|
||||
this._log('Offer QR erstellt');
|
||||
});
|
||||
|
||||
peer.on('connect', () => {
|
||||
peer.send(JSON.stringify({ type: 'identity', peerId: this.myPeerId, name: this.playerName }));
|
||||
this._log('DataChannel offen, sende Identity');
|
||||
});
|
||||
|
||||
peer.on('data', data => {
|
||||
|
|
@ -71,14 +77,19 @@ class MeshNet {
|
|||
}
|
||||
|
||||
async feedAnswer(answerStr) {
|
||||
if (!this._pendingPeer || this._pendingPeer.signalReceived) return;
|
||||
if (!this._pendingPeer || this._pendingPeer.signalReceived) {
|
||||
this._log('feedAnswer ignoriert (bereits verbunden)');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const data = await unpack(decode45(answerStr));
|
||||
this._pendingPeer.peerId = data.id;
|
||||
this._pendingPeer.peer.signal(data.s);
|
||||
this._pendingPeer.signalReceived = true;
|
||||
this._log(`Answer verarbeitet von ${data.id.slice(0, 8)}`);
|
||||
} catch (e) {
|
||||
console.error('feedAnswer error:', e);
|
||||
this._log(`feedAnswer Fehler: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +100,7 @@ class MeshNet {
|
|||
const remoteId = data.id;
|
||||
this.hostPeerId = remoteId;
|
||||
const offer = data.s;
|
||||
this._log(`QR gelesen, signalisiere Host ${remoteId.slice(0, 8)}`);
|
||||
|
||||
const peer = new SimplePeer({ initiator: false, trickle: false, config: { iceServers: [] } });
|
||||
let answerSent = false;
|
||||
|
|
@ -100,11 +112,13 @@ class MeshNet {
|
|||
const packed = await pack({ v: 1, id: this.myPeerId, s: minSignal, to: remoteId });
|
||||
const answerData = encode45(packed);
|
||||
if (this.onanswerready) this.onanswerready(answerData);
|
||||
this._log('Answer QR erstellt');
|
||||
});
|
||||
|
||||
peer.on('connect', () => {
|
||||
this.connections.set(remoteId, peer);
|
||||
peer.send(JSON.stringify({ type: 'identity', peerId: this.myPeerId, name: this.playerName }));
|
||||
this._log(`DataChannel zu Host ${remoteId.slice(0, 8)} offen`);
|
||||
if (this.onpeerconnect) this.onpeerconnect(remoteId);
|
||||
});
|
||||
|
||||
|
|
@ -116,7 +130,10 @@ class MeshNet {
|
|||
});
|
||||
|
||||
peer.on('close', () => this._cleanupPeer(peer));
|
||||
peer.on('error', err => console.error('p2p error:', err));
|
||||
peer.on('error', err => {
|
||||
console.error('p2p error:', err);
|
||||
this._log(`Peer-Fehler: ${err.message}`);
|
||||
});
|
||||
|
||||
peer.signal(offer);
|
||||
this.connections.set(remoteId, peer);
|
||||
|
|
@ -134,7 +151,7 @@ class MeshNet {
|
|||
|
||||
peer.on('connect', () => {
|
||||
if (onConnect) onConnect();
|
||||
// No identity exchange – peerId known from context
|
||||
this._log('DataChannel (Mesh) offen');
|
||||
});
|
||||
|
||||
peer.on('data', data => {
|
||||
|
|
@ -145,7 +162,10 @@ class MeshNet {
|
|||
});
|
||||
|
||||
peer.on('close', () => this._cleanupPeer(peer));
|
||||
peer.on('error', e => console.error('mesh error:', e));
|
||||
peer.on('error', e => {
|
||||
console.error('mesh error:', e);
|
||||
this._log(`Mesh-Fehler: ${e.message}`);
|
||||
});
|
||||
|
||||
return peer;
|
||||
}
|
||||
|
|
@ -154,6 +174,7 @@ class MeshNet {
|
|||
if (this.connections.has(targetPeerId)) return;
|
||||
if (this._pendingMeshPeers.has(targetPeerId)) return;
|
||||
if (this.myPeerId >= targetPeerId) return;
|
||||
this._log(`Mesh zu ${targetPeerId.slice(0, 8)} initiiert`);
|
||||
|
||||
const peer = this._createSimplePeer(true,
|
||||
signal => {
|
||||
|
|
@ -171,6 +192,7 @@ class MeshNet {
|
|||
}
|
||||
|
||||
_handleRelayedSignal(fromPeerId, signal) {
|
||||
this._log(`Relayed-Signal von ${fromPeerId.slice(0, 8)}`);
|
||||
let peer = this.connections.get(fromPeerId) || this._pendingMeshPeers.get(fromPeerId);
|
||||
|
||||
if (!peer) {
|
||||
|
|
@ -192,6 +214,8 @@ class MeshNet {
|
|||
}
|
||||
|
||||
_checkMeshConnections() {
|
||||
const missing = this.roster.filter(pid => pid !== this.myPeerId && !this.connections.has(pid) && this.myPeerId < pid);
|
||||
if (missing.length) this._log(`Prüfe Mesh: ${missing.length} fehlende Verbindungen`);
|
||||
for (const pid of this.roster) {
|
||||
if (pid === this.myPeerId) continue;
|
||||
if (this.connections.has(pid)) continue;
|
||||
|
|
@ -214,6 +238,7 @@ class MeshNet {
|
|||
if (allConnected && this.roster.length > 0) {
|
||||
this._meshReadySent = true;
|
||||
this.sendTo(this.hostPeerId, { type: 'mesh_ready' });
|
||||
this._log('Mesh ready gesendet');
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -221,6 +246,8 @@ class MeshNet {
|
|||
this.roster = this.getPeerIds();
|
||||
this.readyPeers.clear();
|
||||
this.broadcast({ type: 'roster', peers: this.roster.map(id => ({ id, name: this.names.get(id) || '' })) });
|
||||
this.readyPeers.clear();
|
||||
this._log(`Roster broadcast an ${this.roster.length} Peers`);
|
||||
if (this.onreadyupdate) this.onreadyupdate(0, this.roster.length);
|
||||
}
|
||||
|
||||
|
|
@ -236,23 +263,27 @@ class MeshNet {
|
|||
this.connections.delete(existing);
|
||||
}
|
||||
this.connections.set(msg.peerId, peer);
|
||||
this._log(`Identity: ${msg.peerId.slice(0, 8)}`);
|
||||
|
||||
if (this._pendingPeer && this._pendingPeer.peer === peer) {
|
||||
this._pendingPeer.peerId = msg.peerId;
|
||||
this._pendingPeer.connected = true;
|
||||
this._pendingPeer = null;
|
||||
if (this.onpeerconnect) this.onpeerconnect(msg.peerId);
|
||||
this._log(`Host: Peer ${msg.peerId.slice(0, 8)} promoted`);
|
||||
if (this.isHost) {
|
||||
setTimeout(() => this._createPendingPeer(), 300);
|
||||
this._broadcastRoster();
|
||||
}
|
||||
} else {
|
||||
if (this.onpeerconnect) this.onpeerconnect(msg.peerId);
|
||||
this._log(`Mesh: Peer ${msg.peerId.slice(0, 8)} verbunden`);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.type === 'signal_relay') {
|
||||
this._log(`Signal-Relay weitergeleitet an ${msg.to.slice(0, 8)}`);
|
||||
const target = this.connections.get(msg.to) || this._pendingMeshPeers.get(msg.to);
|
||||
if (target) {
|
||||
target.send(JSON.stringify({
|
||||
|
|
@ -274,11 +305,13 @@ class MeshNet {
|
|||
if (msg.peers) msg.peers.forEach(p => { if (p.name) this.names.set(p.id, p.name); });
|
||||
this._meshReadySent = false;
|
||||
this._checkMeshConnections();
|
||||
this._log(`Roster empfangen: ${this.roster.length} Peers`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.type === 'mesh_ready' && this.isHost) {
|
||||
this.readyPeers.add(peerId);
|
||||
this._log(`Mesh ready von ${peerId.slice(0, 8)}`);
|
||||
if (this.onreadyupdate) {
|
||||
this.onreadyupdate(this.readyPeers.size, this.roster.length);
|
||||
}
|
||||
|
|
@ -311,6 +344,7 @@ class MeshNet {
|
|||
const peerId = this._findPeerId(peer);
|
||||
if (peerId) {
|
||||
this.connections.delete(peerId);
|
||||
this._log(`Peer getrennt: ${peerId.slice(0, 8)}`);
|
||||
if (this.onpeerdisconnect) this.onpeerdisconnect(peerId);
|
||||
}
|
||||
|
||||
|
|
@ -366,6 +400,7 @@ class MeshNet {
|
|||
}
|
||||
|
||||
destroy() {
|
||||
this._log('MeshNet wird zerstört');
|
||||
for (const peer of this.connections.values()) {
|
||||
try { peer.destroy(); } catch (e) {}
|
||||
}
|
||||
|
|
|
|||
38
style.css
38
style.css
|
|
@ -476,5 +476,43 @@ footer {
|
|||
background: var(--accent-hover);
|
||||
}
|
||||
|
||||
/* Debug pairing log */
|
||||
#debug-pairing {
|
||||
position: fixed; bottom: 0; left: 8px;
|
||||
width: 320px; max-height: 260px;
|
||||
background: var(--bg-card);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius) var(--radius) 0 0;
|
||||
font-size: 0.75rem;
|
||||
font-family: monospace;
|
||||
z-index: 100;
|
||||
display: none;
|
||||
}
|
||||
.debug-mode #debug-pairing { display: flex; flex-direction: column; }
|
||||
#debug-pairing-header {
|
||||
padding: 4px 8px;
|
||||
font-size: 0.7rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--text-dim);
|
||||
border-bottom: 1px solid var(--border);
|
||||
cursor: default;
|
||||
}
|
||||
#debug-pairing-messages {
|
||||
flex: 1; overflow-y: auto; padding: 6px 8px;
|
||||
max-height: 260px;
|
||||
display: flex; flex-direction: column; gap: 2px;
|
||||
}
|
||||
#debug-pairing-messages div {
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
line-height: 1.3;
|
||||
word-break: break-all;
|
||||
}
|
||||
#debug-pairing-messages div:nth-child(even) {
|
||||
background: rgba(255,255,255,0.03);
|
||||
}
|
||||
|
||||
/* Utility */
|
||||
.hidden { display: none !important; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue