-
Notifications
You must be signed in to change notification settings - Fork 2
/
host.js
77 lines (71 loc) · 2.59 KB
/
host.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import './qr.js';
import './wakelock.js';
import { Gamepads } from './get_gamepads.js';
import { Peer } from './peer.js';
const WEB_GAMEPAD_URL = 'https://geophree.github.io/web-gamepad/';
const letters = 'BCDFGHJKLMNPQRSTVWXZ';
const getLetter = () => letters.charAt(Math.floor(Math.random() * letters.length));
export async function startHost(options) {
if (!window.isSecureContext) {
console.error('web gamepad requires a secure context');
// tell user we require secure context
return;
}
let { webGamepadUrl = WEB_GAMEPAD_URL } = options ?? {};
let roomCode = Array.from({ length: 4 }, getLetter).join('');
const peerId = [...new Uint8Array(await crypto.subtle.digest("SHA-1", new TextEncoder("utf-8").encode(roomCode)))]
.map(x => x.toString(16).padStart(2, '0'))
.join('');
const peer = new Peer(peerId);//, {debug: 3});
window.peer = peer;
peer.on('error', console.error);
peer.on('connection', (conn) => {
conn.on('error', console.error);
conn.on('open', () => {
let heldGamepads = [];
let heldTimestamp = 0;
const target = new EventTarget();
Gamepads.register(target, () => heldGamepads);
conn.on('data', (data) => {
if (data?.type != 'gamepads' || data.timestamp <= heldTimestamp) return;
const oldGamepads = heldGamepads;
heldTimestamp = data.timestamp;
heldGamepads = data.gamepads;
for (const gamepad of heldGamepads) {
const { index, connected } = gamepad;
const oldGamepad = oldGamepads[index];
if (oldGamepad?.connected === connected) continue;
const eventName = (connected) ? 'gamepadconnected' : 'gamepaddisconnected';
const event = new Event(eventName);
event.gamepad = gamepad;
target.dispatchEvent(event);
}
});
conn.on('close', () => {
console.log('connection close');
for (const gamepad of heldGamepads) {
gamepad.connected = false;
}
for (const gamepad of heldGamepads) {
const event = new Event('gamepaddisconnected');
event.gamepad = gamepad;
target.dispatchEvent(event);
}
});
conn.peerConnection.addEventListener("connectionstatechange", (event) => {
if (conn.peerConnection.connectionState === 'disconnected') {
conn.close();
}
});
});
});
return {
getQrCode() {
const playerUrl = new URL(webGamepadUrl);
playerUrl.hash = '?rc=' + roomCode;
const qr = document.createElement('url-qr-code');
qr.href = playerUrl.toString();
return qr;
}
};
}