@@ -25,6 +25,7 @@
|
|
25
25
|
export * from "./engine_networking_files.js";
|
26
26
|
export * from "./engine_networking_instantiate.js";
|
27
27
|
export * from "./engine_networking_utils.js";
|
28
|
+
export * from "./engine_networking_peer.js";
|
28
29
|
export * from "./engine_patcher.js";
|
29
30
|
export * from "./engine_playerview.js";
|
30
31
|
export * from "./engine_physics.js";
|
@@ -22,8 +22,8 @@
|
|
22
22
|
// if the listener is already parented to some object d0nt change it
|
23
23
|
if (listener.parent) return;
|
24
24
|
|
25
|
-
const cam = GameObject.getComponentInParent(this.gameObject, Camera);
|
26
|
-
if (cam) {
|
25
|
+
const cam = this.context.mainCameraComponent || GameObject.getComponentInParent(this.gameObject, Camera);
|
26
|
+
if (cam?.cam) {
|
27
27
|
cam.cam.add(listener);
|
28
28
|
}
|
29
29
|
else
|
@@ -1,11 +1,32 @@
|
|
1
|
-
import
|
2
|
-
import { type DataConnection } from "peerjs";
|
1
|
+
import Peer, { PeerConnectOption } from "peerjs";
|
2
|
+
import { type DataConnection, type PeerJSOption } from "peerjs";
|
3
3
|
import { ConstructorConcrete } from "./engine_types.js";
|
4
4
|
|
5
|
+
let peerOptions: PeerJSOption | undefined = undefined;
|
6
|
+
|
7
|
+
export function getPeerOptions() {
|
8
|
+
return peerOptions;
|
9
|
+
}
|
10
|
+
export function setPeerOptions(opts: PeerJSOption) {
|
11
|
+
peerOptions = opts;
|
12
|
+
}
|
13
|
+
export function getPeerjsInstance(id?: string, opts?: PeerJSOption): Peer {
|
14
|
+
if (!opts) opts = {}
|
15
|
+
opts = {
|
16
|
+
...peerOptions,
|
17
|
+
...opts,
|
18
|
+
}
|
19
|
+
if (id)
|
20
|
+
return new Peer(id, opts);
|
21
|
+
return new Peer(opts);
|
22
|
+
}
|
23
|
+
|
24
|
+
|
25
|
+
|
5
26
|
async function importPeer(): Promise<ConstructorConcrete<Peer>> {
|
6
27
|
const pkg = await import("peerjs");
|
7
28
|
console.log(pkg);
|
8
|
-
if(pkg.default === undefined) return pkg as any;
|
29
|
+
if (pkg.default === undefined) return pkg as any;
|
9
30
|
return pkg.default;
|
10
31
|
}
|
11
32
|
|
@@ -2,18 +2,16 @@
|
|
2
2
|
|
3
3
|
const debug = getParam("debugtypes");
|
4
4
|
|
5
|
-
/**
|
6
|
-
* global types
|
7
|
-
*/
|
8
|
-
const _types = globalThis["__NEEDLE_ENGINE_TYPES"] = globalThis["__NEEDLE_ENGINE_TYPES"] || {};
|
9
5
|
|
10
|
-
|
6
|
+
class _TypeStore {
|
11
7
|
|
12
|
-
|
8
|
+
private _types = {};
|
9
|
+
|
10
|
+
public add(key, type) {
|
13
11
|
if (debug) console.warn("ADD TYPE", key);
|
14
|
-
const existing = _types[key];
|
12
|
+
const existing = this._types[key];
|
15
13
|
if (existing === undefined)
|
16
|
-
_types[key] = type;
|
14
|
+
this._types[key] = type;
|
17
15
|
else {
|
18
16
|
if (debug) {
|
19
17
|
if (existing !== type) {
|
@@ -23,14 +21,14 @@
|
|
23
21
|
}
|
24
22
|
}
|
25
23
|
|
26
|
-
public
|
27
|
-
return _types[key];
|
24
|
+
public get(key) {
|
25
|
+
return this._types[key];
|
28
26
|
}
|
29
27
|
}
|
30
28
|
|
31
29
|
export const $BuiltInTypeFlag = Symbol("BuiltInType");
|
30
|
+
export const TypeStore = new _TypeStore();
|
32
31
|
|
33
|
-
|
34
32
|
/**
|
35
33
|
* add to a class declaration to automatically register it to the TypeStore (required for HMR right now)
|
36
34
|
*
|
@@ -59,6 +59,8 @@
|
|
59
59
|
|
60
60
|
if (url?.startsWith("/")) {
|
61
61
|
const base = useLocalHostUrl ? result : window.location.origin;
|
62
|
+
if(base?.endsWith("/") && url.startsWith("/"))
|
63
|
+
url = url.substring(1);
|
62
64
|
result = base + url;
|
63
65
|
}
|
64
66
|
|
@@ -11,6 +11,7 @@
|
|
11
11
|
import { getParam } from "../engine/engine_utils.js";
|
12
12
|
import { IModel } from "../engine/engine_networking_types.js";
|
13
13
|
import { showBalloonWarning } from "../engine/debug/index.js";
|
14
|
+
import { getPeerjsInstance } from "../engine/engine_networking_peer.js";
|
14
15
|
|
15
16
|
const debug = getParam("debugscreensharing");
|
16
17
|
|
@@ -34,22 +35,30 @@
|
|
34
35
|
|
35
36
|
declare type ScreenCaptureOptions = {
|
36
37
|
device?: ScreenCaptureDevice,
|
38
|
+
constraints?: MediaTrackConstraints,
|
39
|
+
/** Filter video device by id. Alternatively pass in a deviceFilter callback to manually filter available devices */
|
37
40
|
deviceId?: string,
|
38
|
-
|
41
|
+
/** Return false to skip the available device */
|
42
|
+
deviceFilter?: (device: MediaDeviceInfo) => boolean,
|
39
43
|
}
|
40
44
|
|
41
45
|
export class ScreenCapture extends Behaviour implements IPointerClickHandler {
|
42
46
|
|
47
|
+
allowStartOnClick: boolean = true;
|
48
|
+
|
43
49
|
onPointerEnter() {
|
50
|
+
if (!this.allowStartOnClick) return;
|
44
51
|
this.context.input.setCursorPointer();
|
45
52
|
}
|
46
53
|
onPointerExit() {
|
54
|
+
if (!this.allowStartOnClick) return;
|
47
55
|
this.context.input.setCursorNormal();
|
48
56
|
}
|
49
57
|
|
50
|
-
onPointerClick(evt
|
51
|
-
if(
|
52
|
-
if(
|
58
|
+
onPointerClick(evt: PointerEventData) {
|
59
|
+
if (!this.allowStartOnClick) return;
|
60
|
+
if (evt && evt.pointerId !== 0) return;
|
61
|
+
if (this.context.connection.isInRoom === false) return;
|
53
62
|
if (this.isReceiving && this.videoPlayer?.isPlaying) {
|
54
63
|
if (this.videoPlayer)
|
55
64
|
this.videoPlayer.screenspace = !this.videoPlayer.screenspace;
|
@@ -129,6 +138,7 @@
|
|
129
138
|
this._net.addEventListener(PeerEvent.ReceiveVideo, this.onReceiveVideo.bind(this));
|
130
139
|
}
|
131
140
|
|
141
|
+
/** Call to begin screensharing */
|
132
142
|
async share(opts?: ScreenCaptureOptions) {
|
133
143
|
|
134
144
|
if (opts?.device)
|
@@ -277,6 +287,9 @@
|
|
277
287
|
if (id !== options.deviceId)
|
278
288
|
continue;
|
279
289
|
}
|
290
|
+
const useDevice = options?.deviceFilter?.call(this, dev);
|
291
|
+
if (useDevice === false) continue;
|
292
|
+
|
280
293
|
if (opts.video !== false) {
|
281
294
|
if (typeof opts.video === "undefined" || typeof opts.video === "boolean") {
|
282
295
|
opts.video = {};
|
@@ -487,8 +500,8 @@
|
|
487
500
|
this._enabledPeer = true;
|
488
501
|
if (!this._peer) {
|
489
502
|
const peerId = this.getMyPeerId();
|
490
|
-
if(peerId)
|
491
|
-
this._peer =
|
503
|
+
if (peerId)
|
504
|
+
this._peer = getPeerjsInstance(peerId);
|
492
505
|
else console.error("Failed to setup peerjs because we dont have a connection id", this.context.connection.connectionId);
|
493
506
|
}
|
494
507
|
if (this._enabled)
|
@@ -7,6 +7,7 @@
|
|
7
7
|
import * as utils from "../engine/engine_utils.js"
|
8
8
|
import { AudioAnalyser } from "three";
|
9
9
|
import { SendQueue } from "../engine/engine_networking_types.js";
|
10
|
+
import { getPeerjsInstance } from "../engine/engine_networking_peer.js";
|
10
11
|
|
11
12
|
export const noVoip = "noVoip";
|
12
13
|
const debug = utils.getParam("debugvoip");
|
@@ -312,7 +313,7 @@
|
|
312
313
|
return;
|
313
314
|
}
|
314
315
|
|
315
|
-
this.peer =
|
316
|
+
this.peer = getPeerjsInstance();
|
316
317
|
navigator["getUserMedia"] = (navigator["getUserMedia"] || navigator["webkitGetUserMedia"] || navigator["mozGetUserMedia"] || navigator["msGetUserMedia"]);
|