@dcl/sdk 7.3.15-6201184205.commit-767716e → 7.3.15-6201550692.commit-88f3deb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/internal/transports/logger.d.ts +2 -0
- package/internal/transports/logger.js +34 -0
- package/network-transport/client.d.ts +5 -0
- package/network-transport/client.js +65 -0
- package/network-transport/index.d.ts +10 -0
- package/network-transport/index.js +29 -0
- package/network-transport/server.d.ts +2 -0
- package/network-transport/server.js +62 -0
- package/network-transport/state.d.ts +2 -0
- package/network-transport/state.js +11 -0
- package/network-transport/types.d.ts +36 -0
- package/network-transport/types.js +7 -0
- package/network-transport/utils.d.ts +8 -0
- package/network-transport/utils.js +46 -0
- package/package.json +6 -6
- package/src/internal/transports/logger.ts +40 -0
- package/src/network-transport/client.ts +74 -0
- package/src/network-transport/index.ts +45 -0
- package/src/network-transport/server.ts +66 -0
- package/src/network-transport/state.ts +13 -0
- package/src/network-transport/types.ts +41 -0
- package/src/network-transport/utils.ts +67 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
import { CrdtMessageType } from '@dcl/ecs';
|
2
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer';
|
3
|
+
import { readMessage } from '@dcl/ecs/dist/serialization/crdt/message';
|
4
|
+
export function* serializeCrdtMessages(prefix, data, engine) {
|
5
|
+
const buffer = new ReadWriteByteBuffer(data);
|
6
|
+
let message;
|
7
|
+
while ((message = readMessage(buffer))) {
|
8
|
+
const ent = `0x${message.entityId.toString(16)}`;
|
9
|
+
const preface = `${prefix}: ${CrdtMessageType[message.type]} e=${ent}`;
|
10
|
+
if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
11
|
+
yield `${preface}`;
|
12
|
+
}
|
13
|
+
if (message.type === CrdtMessageType.PUT_COMPONENT ||
|
14
|
+
message.type === CrdtMessageType.DELETE_COMPONENT ||
|
15
|
+
message.type === CrdtMessageType.APPEND_VALUE) {
|
16
|
+
const { componentId, timestamp } = message;
|
17
|
+
const data = 'data' in message ? message.data : undefined;
|
18
|
+
try {
|
19
|
+
const c = engine.getComponent(componentId);
|
20
|
+
yield `${preface} c=${c.componentName} t=${timestamp} data=${JSON.stringify((data && c.schema.deserialize(new ReadWriteByteBuffer(data))) || null)}`;
|
21
|
+
}
|
22
|
+
catch {
|
23
|
+
yield `${preface} c=${componentId} t=${timestamp} data=?`;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
else if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
27
|
+
yield preface;
|
28
|
+
}
|
29
|
+
else {
|
30
|
+
yield `${preface} Unknown CrdtMessageType`;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9nZ2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2ludGVybmFsL3RyYW5zcG9ydHMvbG9nZ2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBd0IsZUFBZSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQ2hFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFBO0FBQzVFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQTtBQUV0RSxNQUFNLFNBQVMsQ0FBQyxDQUFDLHFCQUFxQixDQUFDLE1BQWMsRUFBRSxJQUFnQixFQUFFLE1BQWU7SUFDdEYsTUFBTSxNQUFNLEdBQUcsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQTtJQUU1QyxJQUFJLE9BQTJCLENBQUE7SUFFL0IsT0FBTyxDQUFDLE9BQU8sR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRTtRQUN0QyxNQUFNLEdBQUcsR0FBRyxLQUFLLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUE7UUFDaEQsTUFBTSxPQUFPLEdBQUcsR0FBRyxNQUFNLEtBQUssZUFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQTtRQUN0RSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLGFBQWEsRUFBRTtZQUNsRCxNQUFNLEdBQUcsT0FBTyxFQUFFLENBQUE7U0FDbkI7UUFFRCxJQUNFLE9BQU8sQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLGFBQWE7WUFDOUMsT0FBTyxDQUFDLElBQUksS0FBSyxlQUFlLENBQUMsZ0JBQWdCO1lBQ2pELE9BQU8sQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLFlBQVksRUFDN0M7WUFDQSxNQUFNLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxHQUFHLE9BQU8sQ0FBQTtZQUMxQyxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUE7WUFFekQsSUFBSTtnQkFDRixNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFBO2dCQUUxQyxNQUFNLEdBQUcsT0FBTyxNQUFNLENBQUMsQ0FBQyxhQUFhLE1BQU0sU0FBUyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQ3pFLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksbUJBQW1CLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FDdEUsRUFBRSxDQUFBO2FBQ0o7WUFBQyxNQUFNO2dCQUNOLE1BQU0sR0FBRyxPQUFPLE1BQU0sV0FBVyxNQUFNLFNBQVMsU0FBUyxDQUFBO2FBQzFEO1NBQ0Y7YUFBTSxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssZUFBZSxDQUFDLGFBQWEsRUFBRTtZQUN6RCxNQUFNLE9BQU8sQ0FBQTtTQUNkO2FBQU07WUFDTCxNQUFNLEdBQUcsT0FBTywwQkFBMEIsQ0FBQTtTQUMzQztLQUNGO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElFbmdpbmUsIENyZHRNZXNzYWdlLCBDcmR0TWVzc2FnZVR5cGUgfSBmcm9tICdAZGNsL2VjcydcbmltcG9ydCB7IFJlYWRXcml0ZUJ5dGVCdWZmZXIgfSBmcm9tICdAZGNsL2Vjcy9kaXN0L3NlcmlhbGl6YXRpb24vQnl0ZUJ1ZmZlcidcbmltcG9ydCB7IHJlYWRNZXNzYWdlIH0gZnJvbSAnQGRjbC9lY3MvZGlzdC9zZXJpYWxpemF0aW9uL2NyZHQvbWVzc2FnZSdcblxuZXhwb3J0IGZ1bmN0aW9uKiBzZXJpYWxpemVDcmR0TWVzc2FnZXMocHJlZml4OiBzdHJpbmcsIGRhdGE6IFVpbnQ4QXJyYXksIGVuZ2luZTogSUVuZ2luZSkge1xuICBjb25zdCBidWZmZXIgPSBuZXcgUmVhZFdyaXRlQnl0ZUJ1ZmZlcihkYXRhKVxuXG4gIGxldCBtZXNzYWdlOiBDcmR0TWVzc2FnZSB8IG51bGxcblxuICB3aGlsZSAoKG1lc3NhZ2UgPSByZWFkTWVzc2FnZShidWZmZXIpKSkge1xuICAgIGNvbnN0IGVudCA9IGAweCR7bWVzc2FnZS5lbnRpdHlJZC50b1N0cmluZygxNil9YFxuICAgIGNvbnN0IHByZWZhY2UgPSBgJHtwcmVmaXh9OiAke0NyZHRNZXNzYWdlVHlwZVttZXNzYWdlLnR5cGVdfSBlPSR7ZW50fWBcbiAgICBpZiAobWVzc2FnZS50eXBlID09PSBDcmR0TWVzc2FnZVR5cGUuREVMRVRFX0VOVElUWSkge1xuICAgICAgeWllbGQgYCR7cHJlZmFjZX1gXG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgbWVzc2FnZS50eXBlID09PSBDcmR0TWVzc2FnZVR5cGUuUFVUX0NPTVBPTkVOVCB8fFxuICAgICAgbWVzc2FnZS50eXBlID09PSBDcmR0TWVzc2FnZVR5cGUuREVMRVRFX0NPTVBPTkVOVCB8fFxuICAgICAgbWVzc2FnZS50eXBlID09PSBDcmR0TWVzc2FnZVR5cGUuQVBQRU5EX1ZBTFVFXG4gICAgKSB7XG4gICAgICBjb25zdCB7IGNvbXBvbmVudElkLCB0aW1lc3RhbXAgfSA9IG1lc3NhZ2VcbiAgICAgIGNvbnN0IGRhdGEgPSAnZGF0YScgaW4gbWVzc2FnZSA/IG1lc3NhZ2UuZGF0YSA6IHVuZGVmaW5lZFxuXG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBjID0gZW5naW5lLmdldENvbXBvbmVudChjb21wb25lbnRJZClcblxuICAgICAgICB5aWVsZCBgJHtwcmVmYWNlfSBjPSR7Yy5jb21wb25lbnROYW1lfSB0PSR7dGltZXN0YW1wfSBkYXRhPSR7SlNPTi5zdHJpbmdpZnkoXG4gICAgICAgICAgKGRhdGEgJiYgYy5zY2hlbWEuZGVzZXJpYWxpemUobmV3IFJlYWRXcml0ZUJ5dGVCdWZmZXIoZGF0YSkpKSB8fCBudWxsXG4gICAgICAgICl9YFxuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHlpZWxkIGAke3ByZWZhY2V9IGM9JHtjb21wb25lbnRJZH0gdD0ke3RpbWVzdGFtcH0gZGF0YT0/YFxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobWVzc2FnZS50eXBlID09PSBDcmR0TWVzc2FnZVR5cGUuREVMRVRFX0VOVElUWSkge1xuICAgICAgeWllbGQgcHJlZmFjZVxuICAgIH0gZWxzZSB7XG4gICAgICB5aWVsZCBgJHtwcmVmYWNlfSBVbmtub3duIENyZHRNZXNzYWdlVHlwZWBcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { craftMessage, createNetworkManager, encodeString, syncFilter } from './utils';
|
2
|
+
import { engine } from '@dcl/ecs';
|
3
|
+
import { getHeaders } from '~system/SignedFetch';
|
4
|
+
import { MessageType } from './types';
|
5
|
+
export async function createClientTransport({ serverUrl }) {
|
6
|
+
const messagesToProcess = [];
|
7
|
+
return new Promise((resolve, reject) => {
|
8
|
+
try {
|
9
|
+
const ws = new WebSocket(serverUrl);
|
10
|
+
ws.binaryType = 'arraybuffer';
|
11
|
+
ws.onopen = async () => {
|
12
|
+
console.log('WS Server Sync connected');
|
13
|
+
const { headers } = await getHeaders({ url: serverUrl, init: { headers: {} } });
|
14
|
+
ws.send(craftMessage(MessageType.Auth, encodeString(JSON.stringify(headers))));
|
15
|
+
const transport = {
|
16
|
+
filter: syncFilter,
|
17
|
+
send: async (message) => {
|
18
|
+
if (ws.readyState === WebSocket.OPEN) {
|
19
|
+
ws.send(craftMessage(MessageType.Crdt, message));
|
20
|
+
}
|
21
|
+
if (messagesToProcess && messagesToProcess.length) {
|
22
|
+
if (transport.onmessage) {
|
23
|
+
for (const byteArray of messagesToProcess) {
|
24
|
+
transport.onmessage(byteArray);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
}
|
28
|
+
messagesToProcess.length = 0;
|
29
|
+
}
|
30
|
+
};
|
31
|
+
engine.addTransport(transport);
|
32
|
+
};
|
33
|
+
ws.onmessage = (event) => {
|
34
|
+
if (event.data.byteLength) {
|
35
|
+
let offset = 0;
|
36
|
+
const r = new Uint8Array(event.data);
|
37
|
+
const view = new DataView(r.buffer);
|
38
|
+
const msgType = view.getUint8(offset);
|
39
|
+
offset += 1;
|
40
|
+
if (msgType === MessageType.Crdt) {
|
41
|
+
messagesToProcess.push(r.subarray(offset));
|
42
|
+
}
|
43
|
+
else if (msgType === MessageType.Init) {
|
44
|
+
const start = view.getUint32(offset);
|
45
|
+
offset += 4;
|
46
|
+
const size = view.getUint32(offset);
|
47
|
+
offset += 4;
|
48
|
+
const localEntitiesReserved = view.getUint32(offset);
|
49
|
+
offset += 4;
|
50
|
+
resolve(createNetworkManager(localEntitiesReserved, [start, start + size]));
|
51
|
+
messagesToProcess.push(r.subarray(offset));
|
52
|
+
}
|
53
|
+
}
|
54
|
+
};
|
55
|
+
ws.onerror = (e) => {
|
56
|
+
console.error(e);
|
57
|
+
reject(e);
|
58
|
+
};
|
59
|
+
}
|
60
|
+
catch (err) {
|
61
|
+
reject(err);
|
62
|
+
}
|
63
|
+
});
|
64
|
+
}
|
65
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldHdvcmstdHJhbnNwb3J0L2NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFDdEYsT0FBTyxFQUFhLE1BQU0sRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUM1QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUE7QUFFaEQsT0FBTyxFQUFFLFdBQVcsRUFBMEIsTUFBTSxTQUFTLENBQUE7QUFNN0QsTUFBTSxDQUFDLEtBQUssVUFBVSxxQkFBcUIsQ0FBQyxFQUFFLFNBQVMsRUFBeUI7SUFDOUUsTUFBTSxpQkFBaUIsR0FBaUIsRUFBRSxDQUFBO0lBRTFDLE9BQU8sSUFBSSxPQUFPLENBQWlCLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3JELElBQUk7WUFDRixNQUFNLEVBQUUsR0FBRyxJQUFJLFNBQVMsQ0FBQyxTQUFTLENBQVcsQ0FBQTtZQUM3QyxFQUFFLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQTtZQUU3QixFQUFFLENBQUMsTUFBTSxHQUFHLEtBQUssSUFBSSxFQUFFO2dCQUNyQixPQUFPLENBQUMsR0FBRyxDQUFDLDBCQUEwQixDQUFDLENBQUE7Z0JBQ3ZDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQTtnQkFDL0UsRUFBRSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtnQkFFOUUsTUFBTSxTQUFTLEdBQWM7b0JBQzNCLE1BQU0sRUFBRSxVQUFVO29CQUNsQixJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQW1CLEVBQUUsRUFBRTt3QkFDbEMsSUFBSSxFQUFFLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxJQUFJLEVBQUU7NEJBQ3BDLEVBQUUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQTt5QkFDakQ7d0JBQ0QsSUFBSSxpQkFBaUIsSUFBSSxpQkFBaUIsQ0FBQyxNQUFNLEVBQUU7NEJBQ2pELElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRTtnQ0FDdkIsS0FBSyxNQUFNLFNBQVMsSUFBSSxpQkFBaUIsRUFBRTtvQ0FDekMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtpQ0FDL0I7NkJBQ0Y7eUJBQ0Y7d0JBQ0QsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQTtvQkFDOUIsQ0FBQztpQkFDRixDQUFBO2dCQUNELE1BQU0sQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDaEMsQ0FBQyxDQUFBO1lBRUQsRUFBRSxDQUFDLFNBQVMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUN2QixJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFO29CQUN6QixJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUE7b0JBQ2QsTUFBTSxDQUFDLEdBQUcsSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO29CQUNwQyxNQUFNLElBQUksR0FBRyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUE7b0JBQ25DLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUE7b0JBQ3JDLE1BQU0sSUFBSSxDQUFDLENBQUE7b0JBRVgsSUFBSSxPQUFPLEtBQUssV0FBVyxDQUFDLElBQUksRUFBRTt3QkFDaEMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtxQkFDM0M7eUJBQU0sSUFBSSxPQUFPLEtBQUssV0FBVyxDQUFDLElBQUksRUFBRTt3QkFDdkMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQTt3QkFDcEMsTUFBTSxJQUFJLENBQUMsQ0FBQTt3QkFDWCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFBO3dCQUNuQyxNQUFNLElBQUksQ0FBQyxDQUFBO3dCQUNYLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQTt3QkFDcEQsTUFBTSxJQUFJLENBQUMsQ0FBQTt3QkFDWCxPQUFPLENBQUMsb0JBQW9CLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTt3QkFDM0UsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQTtxQkFDM0M7aUJBQ0Y7WUFDSCxDQUFDLENBQUE7WUFFRCxFQUFFLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2pCLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7Z0JBQ2hCLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUNYLENBQUMsQ0FBQTtTQUNGO1FBQUMsT0FBTyxHQUFHLEVBQUU7WUFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7U0FDWjtJQUNILENBQUMsQ0FBQyxDQUFBO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGNyYWZ0TWVzc2FnZSwgY3JlYXRlTmV0d29ya01hbmFnZXIsIGVuY29kZVN0cmluZywgc3luY0ZpbHRlciB9IGZyb20gJy4vdXRpbHMnXG5pbXBvcnQgeyBUcmFuc3BvcnQsIGVuZ2luZSB9IGZyb20gJ0BkY2wvZWNzJ1xuaW1wb3J0IHsgZ2V0SGVhZGVycyB9IGZyb20gJ35zeXN0ZW0vU2lnbmVkRmV0Y2gnXG5cbmltcG9ydCB7IE1lc3NhZ2VUeXBlLCBOZXR3b3JrTWFuYWdlciwgU29ja2V0IH0gZnJvbSAnLi90eXBlcydcblxuZXhwb3J0IHR5cGUgQ2xpZW50VHJhbnNwb3J0Q29uZmlnID0ge1xuICBzZXJ2ZXJVcmw6IHN0cmluZ1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ2xpZW50VHJhbnNwb3J0KHsgc2VydmVyVXJsIH06IENsaWVudFRyYW5zcG9ydENvbmZpZyk6IFByb21pc2U8TmV0d29ya01hbmFnZXI+IHtcbiAgY29uc3QgbWVzc2FnZXNUb1Byb2Nlc3M6IFVpbnQ4QXJyYXlbXSA9IFtdXG5cbiAgcmV0dXJuIG5ldyBQcm9taXNlPE5ldHdvcmtNYW5hZ2VyPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHdzID0gbmV3IFdlYlNvY2tldChzZXJ2ZXJVcmwpIGFzIFNvY2tldFxuICAgICAgd3MuYmluYXJ5VHlwZSA9ICdhcnJheWJ1ZmZlcidcblxuICAgICAgd3Mub25vcGVuID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnV1MgU2VydmVyIFN5bmMgY29ubmVjdGVkJylcbiAgICAgICAgY29uc3QgeyBoZWFkZXJzIH0gPSBhd2FpdCBnZXRIZWFkZXJzKHsgdXJsOiBzZXJ2ZXJVcmwsIGluaXQ6IHsgaGVhZGVyczoge30gfSB9KVxuICAgICAgICB3cy5zZW5kKGNyYWZ0TWVzc2FnZShNZXNzYWdlVHlwZS5BdXRoLCBlbmNvZGVTdHJpbmcoSlNPTi5zdHJpbmdpZnkoaGVhZGVycykpKSlcblxuICAgICAgICBjb25zdCB0cmFuc3BvcnQ6IFRyYW5zcG9ydCA9IHtcbiAgICAgICAgICBmaWx0ZXI6IHN5bmNGaWx0ZXIsXG4gICAgICAgICAgc2VuZDogYXN5bmMgKG1lc3NhZ2U6IFVpbnQ4QXJyYXkpID0+IHtcbiAgICAgICAgICAgIGlmICh3cy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xuICAgICAgICAgICAgICB3cy5zZW5kKGNyYWZ0TWVzc2FnZShNZXNzYWdlVHlwZS5DcmR0LCBtZXNzYWdlKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtZXNzYWdlc1RvUHJvY2VzcyAmJiBtZXNzYWdlc1RvUHJvY2Vzcy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgaWYgKHRyYW5zcG9ydC5vbm1lc3NhZ2UpIHtcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGJ5dGVBcnJheSBvZiBtZXNzYWdlc1RvUHJvY2Vzcykge1xuICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0Lm9ubWVzc2FnZShieXRlQXJyYXkpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBtZXNzYWdlc1RvUHJvY2Vzcy5sZW5ndGggPSAwXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVuZ2luZS5hZGRUcmFuc3BvcnQodHJhbnNwb3J0KVxuICAgICAgfVxuXG4gICAgICB3cy5vbm1lc3NhZ2UgPSAoZXZlbnQpID0+IHtcbiAgICAgICAgaWYgKGV2ZW50LmRhdGEuYnl0ZUxlbmd0aCkge1xuICAgICAgICAgIGxldCBvZmZzZXQgPSAwXG4gICAgICAgICAgY29uc3QgciA9IG5ldyBVaW50OEFycmF5KGV2ZW50LmRhdGEpXG4gICAgICAgICAgY29uc3QgdmlldyA9IG5ldyBEYXRhVmlldyhyLmJ1ZmZlcilcbiAgICAgICAgICBjb25zdCBtc2dUeXBlID0gdmlldy5nZXRVaW50OChvZmZzZXQpXG4gICAgICAgICAgb2Zmc2V0ICs9IDFcblxuICAgICAgICAgIGlmIChtc2dUeXBlID09PSBNZXNzYWdlVHlwZS5DcmR0KSB7XG4gICAgICAgICAgICBtZXNzYWdlc1RvUHJvY2Vzcy5wdXNoKHIuc3ViYXJyYXkob2Zmc2V0KSlcbiAgICAgICAgICB9IGVsc2UgaWYgKG1zZ1R5cGUgPT09IE1lc3NhZ2VUeXBlLkluaXQpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0ID0gdmlldy5nZXRVaW50MzIob2Zmc2V0KVxuICAgICAgICAgICAgb2Zmc2V0ICs9IDRcbiAgICAgICAgICAgIGNvbnN0IHNpemUgPSB2aWV3LmdldFVpbnQzMihvZmZzZXQpXG4gICAgICAgICAgICBvZmZzZXQgKz0gNFxuICAgICAgICAgICAgY29uc3QgbG9jYWxFbnRpdGllc1Jlc2VydmVkID0gdmlldy5nZXRVaW50MzIob2Zmc2V0KVxuICAgICAgICAgICAgb2Zmc2V0ICs9IDRcbiAgICAgICAgICAgIHJlc29sdmUoY3JlYXRlTmV0d29ya01hbmFnZXIobG9jYWxFbnRpdGllc1Jlc2VydmVkLCBbc3RhcnQsIHN0YXJ0ICsgc2l6ZV0pKVxuICAgICAgICAgICAgbWVzc2FnZXNUb1Byb2Nlc3MucHVzaChyLnN1YmFycmF5KG9mZnNldCkpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHdzLm9uZXJyb3IgPSAoZSkgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKGUpXG4gICAgICAgIHJlamVjdChlKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgcmVqZWN0KGVycilcbiAgICB9XG4gIH0pXG59XG4iXX0=
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { NetworkManager, ServerTransportConfig } from './types';
|
2
|
+
import { ClientTransportConfig } from './client';
|
3
|
+
export { NetworkManager } from './types';
|
4
|
+
export type NetworkTransportConfig = ClientTransportConfig & Partial<ServerTransportConfig>;
|
5
|
+
export declare let connected: boolean;
|
6
|
+
export declare let reservedLocalEntities: number;
|
7
|
+
export declare function createNetworkManager(config: NetworkTransportConfig): Promise<NetworkManager>;
|
8
|
+
export declare const PlayersConnected: import("@dcl/ecs").MapComponentDefinition<import("@dcl/ecs").MapResult<{
|
9
|
+
usersId: import("@dcl/ecs").ISchema<string[]>;
|
10
|
+
}>>;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { isServer } from '~system/EngineApi';
|
2
|
+
import { Schemas, engine } from '@dcl/ecs';
|
3
|
+
import { createServerTransport } from './server';
|
4
|
+
import { createClientTransport } from './client';
|
5
|
+
export let connected = false;
|
6
|
+
const DEFAULT_NETWORK_ENTITY_LIMIT_SERVER = 512;
|
7
|
+
const DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT = 100;
|
8
|
+
const DEFAULT_RESERVED_LOCAL_ENTITIES = 2560;
|
9
|
+
export let reservedLocalEntities;
|
10
|
+
export async function createNetworkManager(config) {
|
11
|
+
if (connected) {
|
12
|
+
throw new Error('Transport is already created');
|
13
|
+
}
|
14
|
+
const serverConfig = {
|
15
|
+
networkEntitiesLimit: config.networkEntitiesLimit ?? {
|
16
|
+
serverLimit: DEFAULT_NETWORK_ENTITY_LIMIT_SERVER,
|
17
|
+
clientLimit: DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT
|
18
|
+
},
|
19
|
+
reservedLocalEntities: config.reservedLocalEntities || DEFAULT_RESERVED_LOCAL_ENTITIES
|
20
|
+
};
|
21
|
+
reservedLocalEntities = serverConfig.reservedLocalEntities;
|
22
|
+
const networkFactory = isServer && (await isServer({})).isServer ? createServerTransport(serverConfig) : createClientTransport(config);
|
23
|
+
connected = true;
|
24
|
+
return networkFactory;
|
25
|
+
}
|
26
|
+
export const PlayersConnected = engine.defineComponent('chore:network:players', {
|
27
|
+
usersId: Schemas.Array(Schemas.String)
|
28
|
+
});
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay10cmFuc3BvcnQvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBRzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQzFDLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUNoRCxPQUFPLEVBQXlCLHFCQUFxQixFQUFFLE1BQU0sVUFBVSxDQUFBO0FBTXZFLE1BQU0sQ0FBQyxJQUFJLFNBQVMsR0FBRyxLQUFLLENBQUE7QUFFNUIsTUFBTSxtQ0FBbUMsR0FBRyxHQUFHLENBQUE7QUFDL0MsTUFBTSxtQ0FBbUMsR0FBRyxHQUFHLENBQUE7QUFDL0MsTUFBTSwrQkFBK0IsR0FBRyxJQUFJLENBQUE7QUFFNUMsTUFBTSxDQUFDLElBQUkscUJBQTZCLENBQUE7QUFLeEMsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FBQyxNQUE4QjtJQUN2RSxJQUFJLFNBQVMsRUFBRTtRQUNiLE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQTtLQUNoRDtJQUVELE1BQU0sWUFBWSxHQUFHO1FBQ25CLG9CQUFvQixFQUFFLE1BQU0sQ0FBQyxvQkFBb0IsSUFBSTtZQUNuRCxXQUFXLEVBQUUsbUNBQW1DO1lBQ2hELFdBQVcsRUFBRSxtQ0FBbUM7U0FDakQ7UUFDRCxxQkFBcUIsRUFBRSxNQUFNLENBQUMscUJBQXFCLElBQUksK0JBQStCO0tBQ3ZGLENBQUE7SUFDRCxxQkFBcUIsR0FBRyxZQUFZLENBQUMscUJBQXFCLENBQUE7SUFFMUQsTUFBTSxjQUFjLEdBQ2xCLFFBQVEsSUFBSSxDQUFDLE1BQU0sUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxxQkFBcUIsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDakgsU0FBUyxHQUFHLElBQUksQ0FBQTtJQUNoQixPQUFPLGNBQWMsQ0FBQTtBQUN2QixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsRUFBRTtJQUM5RSxPQUFPLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO0NBQ3ZDLENBQUMsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzU2VydmVyIH0gZnJvbSAnfnN5c3RlbS9FbmdpbmVBcGknXG5cbmltcG9ydCB7IE5ldHdvcmtNYW5hZ2VyLCBTZXJ2ZXJUcmFuc3BvcnRDb25maWcgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgU2NoZW1hcywgZW5naW5lIH0gZnJvbSAnQGRjbC9lY3MnXG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXJUcmFuc3BvcnQgfSBmcm9tICcuL3NlcnZlcidcbmltcG9ydCB7IENsaWVudFRyYW5zcG9ydENvbmZpZywgY3JlYXRlQ2xpZW50VHJhbnNwb3J0IH0gZnJvbSAnLi9jbGllbnQnXG5cbmV4cG9ydCB7IE5ldHdvcmtNYW5hZ2VyIH0gZnJvbSAnLi90eXBlcydcblxuZXhwb3J0IHR5cGUgTmV0d29ya1RyYW5zcG9ydENvbmZpZyA9IENsaWVudFRyYW5zcG9ydENvbmZpZyAmIFBhcnRpYWw8U2VydmVyVHJhbnNwb3J0Q29uZmlnPlxuXG5leHBvcnQgbGV0IGNvbm5lY3RlZCA9IGZhbHNlXG5cbmNvbnN0IERFRkFVTFRfTkVUV09SS19FTlRJVFlfTElNSVRfU0VSVkVSID0gNTEyXG5jb25zdCBERUZBVUxUX05FVFdPUktfRU5USVRZX0xJTUlUX0NMSUVOVCA9IDEwMFxuY29uc3QgREVGQVVMVF9SRVNFUlZFRF9MT0NBTF9FTlRJVElFUyA9IDI1NjBcblxuZXhwb3J0IGxldCByZXNlcnZlZExvY2FsRW50aXRpZXM6IG51bWJlclxuLyoqXG4gKiBAYWxwaGFcbiAqIENvbm5lY3QgdG8gQ1JEVCBzZXJ2ZXJcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNyZWF0ZU5ldHdvcmtNYW5hZ2VyKGNvbmZpZzogTmV0d29ya1RyYW5zcG9ydENvbmZpZyk6IFByb21pc2U8TmV0d29ya01hbmFnZXI+IHtcbiAgaWYgKGNvbm5lY3RlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3J0IGlzIGFscmVhZHkgY3JlYXRlZCcpXG4gIH1cblxuICBjb25zdCBzZXJ2ZXJDb25maWcgPSB7XG4gICAgbmV0d29ya0VudGl0aWVzTGltaXQ6IGNvbmZpZy5uZXR3b3JrRW50aXRpZXNMaW1pdCA/PyB7XG4gICAgICBzZXJ2ZXJMaW1pdDogREVGQVVMVF9ORVRXT1JLX0VOVElUWV9MSU1JVF9TRVJWRVIsXG4gICAgICBjbGllbnRMaW1pdDogREVGQVVMVF9ORVRXT1JLX0VOVElUWV9MSU1JVF9DTElFTlRcbiAgICB9LFxuICAgIHJlc2VydmVkTG9jYWxFbnRpdGllczogY29uZmlnLnJlc2VydmVkTG9jYWxFbnRpdGllcyB8fCBERUZBVUxUX1JFU0VSVkVEX0xPQ0FMX0VOVElUSUVTXG4gIH1cbiAgcmVzZXJ2ZWRMb2NhbEVudGl0aWVzID0gc2VydmVyQ29uZmlnLnJlc2VydmVkTG9jYWxFbnRpdGllc1xuXG4gIGNvbnN0IG5ldHdvcmtGYWN0b3J5ID1cbiAgICBpc1NlcnZlciAmJiAoYXdhaXQgaXNTZXJ2ZXIoe30pKS5pc1NlcnZlciA/IGNyZWF0ZVNlcnZlclRyYW5zcG9ydChzZXJ2ZXJDb25maWcpIDogY3JlYXRlQ2xpZW50VHJhbnNwb3J0KGNvbmZpZylcbiAgY29ubmVjdGVkID0gdHJ1ZVxuICByZXR1cm4gbmV0d29ya0ZhY3Rvcnlcbn1cblxuZXhwb3J0IGNvbnN0IFBsYXllcnNDb25uZWN0ZWQgPSBlbmdpbmUuZGVmaW5lQ29tcG9uZW50KCdjaG9yZTpuZXR3b3JrOnBsYXllcnMnLCB7XG4gIHVzZXJzSWQ6IFNjaGVtYXMuQXJyYXkoU2NoZW1hcy5TdHJpbmcpXG59KVxuIl19
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { engine, SyncComponents } from '@dcl/ecs';
|
2
|
+
import { engineToCrdt } from './state';
|
3
|
+
import { syncFilter, createNetworkManager } from './utils';
|
4
|
+
import { PlayersConnected } from '.';
|
5
|
+
export async function createServerTransport(config) {
|
6
|
+
const connectedClients = new Set();
|
7
|
+
engine.addTransport({
|
8
|
+
send: async (message) => {
|
9
|
+
if (message.byteLength) {
|
10
|
+
globalThis.updateCRDTState(engineToCrdt(engine));
|
11
|
+
}
|
12
|
+
},
|
13
|
+
filter: syncFilter
|
14
|
+
});
|
15
|
+
let time = 0;
|
16
|
+
function initialCrdtState(dt) {
|
17
|
+
time += dt;
|
18
|
+
if (time >= 1) {
|
19
|
+
globalThis.updateCRDTState(engineToCrdt(engine));
|
20
|
+
engine.removeSystem(initialCrdtState);
|
21
|
+
}
|
22
|
+
}
|
23
|
+
engine.addSystem(initialCrdtState);
|
24
|
+
globalThis.registerScene(config, (event) => {
|
25
|
+
const { type } = event;
|
26
|
+
if (type === 'open') {
|
27
|
+
const { clientId, client } = event;
|
28
|
+
const transport = {
|
29
|
+
filter: (message) => {
|
30
|
+
if (!connectedClients.has(clientId))
|
31
|
+
return false;
|
32
|
+
return syncFilter(message);
|
33
|
+
},
|
34
|
+
send: async (message) => {
|
35
|
+
if (message.byteLength > 0) {
|
36
|
+
await client.sendCrdtMessage(message);
|
37
|
+
}
|
38
|
+
if (transport.onmessage) {
|
39
|
+
const messages = client.getMessages();
|
40
|
+
for (const byteArray of messages) {
|
41
|
+
transport.onmessage(byteArray);
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}
|
45
|
+
};
|
46
|
+
engine.addTransport(transport);
|
47
|
+
connectedClients.add(event.clientId);
|
48
|
+
}
|
49
|
+
else if (type === 'close') {
|
50
|
+
connectedClients.delete(event.clientId);
|
51
|
+
}
|
52
|
+
PlayersConnected.createOrReplace(players, { usersId: [...connectedClients.values()].map(String) });
|
53
|
+
});
|
54
|
+
const networkEntityFactory = createNetworkManager(config.reservedLocalEntities, [
|
55
|
+
config.reservedLocalEntities,
|
56
|
+
config.reservedLocalEntities + config.networkEntitiesLimit.serverLimit
|
57
|
+
]);
|
58
|
+
const players = networkEntityFactory.addEntity();
|
59
|
+
SyncComponents.create(players, { componentIds: [PlayersConnected.componentId] });
|
60
|
+
return networkEntityFactory;
|
61
|
+
}
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL25ldHdvcmstdHJhbnNwb3J0L3NlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBYSxNQUFNLFVBQVUsQ0FBQTtBQUM1RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFBO0FBQ3RDLE9BQU8sRUFBRSxVQUFVLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUE7QUFFMUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sR0FBRyxDQUFBO0FBRXBDLE1BQU0sQ0FBQyxLQUFLLFVBQVUscUJBQXFCLENBQUMsTUFBNkI7SUFDdkUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFBO0lBQzFDLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDbEIsSUFBSSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRTtZQUN0QixJQUFJLE9BQU8sQ0FBQyxVQUFVLEVBQUU7Z0JBQ3RCLFVBQVUsQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7YUFDakQ7UUFDSCxDQUFDO1FBQ0QsTUFBTSxFQUFFLFVBQVU7S0FDbkIsQ0FBQyxDQUFBO0lBRUYsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFBO0lBQ1osU0FBUyxnQkFBZ0IsQ0FBQyxFQUFVO1FBQ2xDLElBQUksSUFBSSxFQUFFLENBQUE7UUFDVixJQUFJLElBQUksSUFBSSxDQUFDLEVBQUU7WUFDYixVQUFVLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO1lBQ2hELE1BQU0sQ0FBQyxZQUFZLENBQUMsZ0JBQWdCLENBQUMsQ0FBQTtTQUN0QztJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLENBQUE7SUFDbEMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLEVBQUUsRUFBRTtRQUN6QyxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFBO1FBQ3RCLElBQUksSUFBSSxLQUFLLE1BQU0sRUFBRTtZQUNuQixNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQTtZQUNsQyxNQUFNLFNBQVMsR0FBYztnQkFDM0IsTUFBTSxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUU7b0JBQ2xCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO3dCQUFFLE9BQU8sS0FBSyxDQUFBO29CQUNqRCxPQUFPLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQTtnQkFDNUIsQ0FBQztnQkFDRCxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO29CQUN0QixJQUFJLE9BQU8sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxFQUFFO3dCQUMxQixNQUFNLE1BQU0sQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUE7cUJBQ3RDO29CQUVELElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRTt3QkFDdkIsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFBO3dCQUNyQyxLQUFLLE1BQU0sU0FBUyxJQUFJLFFBQVEsRUFBRTs0QkFDaEMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTt5QkFDL0I7cUJBQ0Y7Z0JBQ0gsQ0FBQzthQUNGLENBQUE7WUFFRCxNQUFNLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQzlCLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUE7U0FDckM7YUFBTSxJQUFJLElBQUksS0FBSyxPQUFPLEVBQUU7WUFDM0IsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtTQUN4QztRQUNELGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxPQUFPLEVBQUUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQTtJQUNwRyxDQUFDLENBQUMsQ0FBQTtJQUVGLE1BQU0sb0JBQW9CLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxDQUFDLHFCQUFxQixFQUFFO1FBQzlFLE1BQU0sQ0FBQyxxQkFBcUI7UUFDNUIsTUFBTSxDQUFDLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXO0tBQ3ZFLENBQUMsQ0FBQTtJQUNGLE1BQU0sT0FBTyxHQUFHLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxDQUFBO0lBQ2hELGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUUsWUFBWSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQ2hGLE9BQU8sb0JBQW9CLENBQUE7QUFDN0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGVuZ2luZSwgU3luY0NvbXBvbmVudHMsIFRyYW5zcG9ydCB9IGZyb20gJ0BkY2wvZWNzJ1xuaW1wb3J0IHsgZW5naW5lVG9DcmR0IH0gZnJvbSAnLi9zdGF0ZSdcbmltcG9ydCB7IHN5bmNGaWx0ZXIsIGNyZWF0ZU5ldHdvcmtNYW5hZ2VyIH0gZnJvbSAnLi91dGlscydcbmltcG9ydCB7IE5ldHdvcmtNYW5hZ2VyLCBTZXJ2ZXJUcmFuc3BvcnRDb25maWcgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgUGxheWVyc0Nvbm5lY3RlZCB9IGZyb20gJy4nXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTZXJ2ZXJUcmFuc3BvcnQoY29uZmlnOiBTZXJ2ZXJUcmFuc3BvcnRDb25maWcpOiBQcm9taXNlPE5ldHdvcmtNYW5hZ2VyPiB7XG4gIGNvbnN0IGNvbm5lY3RlZENsaWVudHMgPSBuZXcgU2V0PHN0cmluZz4oKVxuICBlbmdpbmUuYWRkVHJhbnNwb3J0KHtcbiAgICBzZW5kOiBhc3luYyAobWVzc2FnZSkgPT4ge1xuICAgICAgaWYgKG1lc3NhZ2UuYnl0ZUxlbmd0aCkge1xuICAgICAgICBnbG9iYWxUaGlzLnVwZGF0ZUNSRFRTdGF0ZShlbmdpbmVUb0NyZHQoZW5naW5lKSlcbiAgICAgIH1cbiAgICB9LFxuICAgIGZpbHRlcjogc3luY0ZpbHRlclxuICB9KVxuXG4gIGxldCB0aW1lID0gMFxuICBmdW5jdGlvbiBpbml0aWFsQ3JkdFN0YXRlKGR0OiBudW1iZXIpIHtcbiAgICB0aW1lICs9IGR0XG4gICAgaWYgKHRpbWUgPj0gMSkge1xuICAgICAgZ2xvYmFsVGhpcy51cGRhdGVDUkRUU3RhdGUoZW5naW5lVG9DcmR0KGVuZ2luZSkpXG4gICAgICBlbmdpbmUucmVtb3ZlU3lzdGVtKGluaXRpYWxDcmR0U3RhdGUpXG4gICAgfVxuICB9XG5cbiAgZW5naW5lLmFkZFN5c3RlbShpbml0aWFsQ3JkdFN0YXRlKVxuICBnbG9iYWxUaGlzLnJlZ2lzdGVyU2NlbmUoY29uZmlnLCAoZXZlbnQpID0+IHtcbiAgICBjb25zdCB7IHR5cGUgfSA9IGV2ZW50XG4gICAgaWYgKHR5cGUgPT09ICdvcGVuJykge1xuICAgICAgY29uc3QgeyBjbGllbnRJZCwgY2xpZW50IH0gPSBldmVudFxuICAgICAgY29uc3QgdHJhbnNwb3J0OiBUcmFuc3BvcnQgPSB7XG4gICAgICAgIGZpbHRlcjogKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICBpZiAoIWNvbm5lY3RlZENsaWVudHMuaGFzKGNsaWVudElkKSkgcmV0dXJuIGZhbHNlXG4gICAgICAgICAgcmV0dXJuIHN5bmNGaWx0ZXIobWVzc2FnZSlcbiAgICAgICAgfSxcbiAgICAgICAgc2VuZDogYXN5bmMgKG1lc3NhZ2UpID0+IHtcbiAgICAgICAgICBpZiAobWVzc2FnZS5ieXRlTGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgYXdhaXQgY2xpZW50LnNlbmRDcmR0TWVzc2FnZShtZXNzYWdlKVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0cmFuc3BvcnQub25tZXNzYWdlKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlcyA9IGNsaWVudC5nZXRNZXNzYWdlcygpXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGJ5dGVBcnJheSBvZiBtZXNzYWdlcykge1xuICAgICAgICAgICAgICB0cmFuc3BvcnQub25tZXNzYWdlKGJ5dGVBcnJheSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZW5naW5lLmFkZFRyYW5zcG9ydCh0cmFuc3BvcnQpXG4gICAgICBjb25uZWN0ZWRDbGllbnRzLmFkZChldmVudC5jbGllbnRJZClcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdjbG9zZScpIHtcbiAgICAgIGNvbm5lY3RlZENsaWVudHMuZGVsZXRlKGV2ZW50LmNsaWVudElkKVxuICAgIH1cbiAgICBQbGF5ZXJzQ29ubmVjdGVkLmNyZWF0ZU9yUmVwbGFjZShwbGF5ZXJzLCB7IHVzZXJzSWQ6IFsuLi5jb25uZWN0ZWRDbGllbnRzLnZhbHVlcygpXS5tYXAoU3RyaW5nKSB9KVxuICB9KVxuXG4gIGNvbnN0IG5ldHdvcmtFbnRpdHlGYWN0b3J5ID0gY3JlYXRlTmV0d29ya01hbmFnZXIoY29uZmlnLnJlc2VydmVkTG9jYWxFbnRpdGllcywgW1xuICAgIGNvbmZpZy5yZXNlcnZlZExvY2FsRW50aXRpZXMsXG4gICAgY29uZmlnLnJlc2VydmVkTG9jYWxFbnRpdGllcyArIGNvbmZpZy5uZXR3b3JrRW50aXRpZXNMaW1pdC5zZXJ2ZXJMaW1pdFxuICBdKVxuICBjb25zdCBwbGF5ZXJzID0gbmV0d29ya0VudGl0eUZhY3RvcnkuYWRkRW50aXR5KClcbiAgU3luY0NvbXBvbmVudHMuY3JlYXRlKHBsYXllcnMsIHsgY29tcG9uZW50SWRzOiBbUGxheWVyc0Nvbm5lY3RlZC5jb21wb25lbnRJZF0gfSlcbiAgcmV0dXJuIG5ldHdvcmtFbnRpdHlGYWN0b3J5XG59XG4iXX0=
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer';
|
2
|
+
import { SyncComponents } from '@dcl/ecs';
|
3
|
+
export function engineToCrdt(engine) {
|
4
|
+
const crdtBuffer = new ReadWriteByteBuffer();
|
5
|
+
const syncEntities = new Set(Array.from(engine.getEntitiesWith(SyncComponents)).map(($) => $[0]));
|
6
|
+
for (const itComponentDefinition of engine.componentsIter()) {
|
7
|
+
itComponentDefinition.dumpCrdtStateToBuffer(crdtBuffer, (entity) => syncEntities.has(entity));
|
8
|
+
}
|
9
|
+
return crdtBuffer.toBinary();
|
10
|
+
}
|
11
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay10cmFuc3BvcnQvc3RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0NBQXdDLENBQUE7QUFDNUUsT0FBTyxFQUFXLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQTtBQUVsRCxNQUFNLFVBQVUsWUFBWSxDQUFDLE1BQWU7SUFDMUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxtQkFBbUIsRUFBRSxDQUFBO0lBQzVDLE1BQU0sWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVqRyxLQUFLLE1BQU0scUJBQXFCLElBQUksTUFBTSxDQUFDLGNBQWMsRUFBRSxFQUFFO1FBQzNELHFCQUFxQixDQUFDLHFCQUFxQixDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO0tBQzlGO0lBRUQsT0FBTyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUE7QUFDOUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlYWRXcml0ZUJ5dGVCdWZmZXIgfSBmcm9tICdAZGNsL2Vjcy9kaXN0L3NlcmlhbGl6YXRpb24vQnl0ZUJ1ZmZlcidcbmltcG9ydCB7IElFbmdpbmUsIFN5bmNDb21wb25lbnRzIH0gZnJvbSAnQGRjbC9lY3MnXG5cbmV4cG9ydCBmdW5jdGlvbiBlbmdpbmVUb0NyZHQoZW5naW5lOiBJRW5naW5lKTogVWludDhBcnJheSB7XG4gIGNvbnN0IGNyZHRCdWZmZXIgPSBuZXcgUmVhZFdyaXRlQnl0ZUJ1ZmZlcigpXG4gIGNvbnN0IHN5bmNFbnRpdGllcyA9IG5ldyBTZXQoQXJyYXkuZnJvbShlbmdpbmUuZ2V0RW50aXRpZXNXaXRoKFN5bmNDb21wb25lbnRzKSkubWFwKCgkKSA9PiAkWzBdKSlcblxuICBmb3IgKGNvbnN0IGl0Q29tcG9uZW50RGVmaW5pdGlvbiBvZiBlbmdpbmUuY29tcG9uZW50c0l0ZXIoKSkge1xuICAgIGl0Q29tcG9uZW50RGVmaW5pdGlvbi5kdW1wQ3JkdFN0YXRlVG9CdWZmZXIoY3JkdEJ1ZmZlciwgKGVudGl0eSkgPT4gc3luY0VudGl0aWVzLmhhcyhlbnRpdHkpKVxuICB9XG5cbiAgcmV0dXJuIGNyZHRCdWZmZXIudG9CaW5hcnkoKVxufVxuIl19
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/// <reference types="@dcl/js-runtime" />
|
2
|
+
import { Entity, engine } from '@dcl/ecs';
|
3
|
+
export type Socket = WebSocket & {
|
4
|
+
binaryType: string;
|
5
|
+
send(data: string | Uint8Array): void;
|
6
|
+
};
|
7
|
+
export type NetworkManager = {
|
8
|
+
addEntity(theEngine: typeof engine): Entity;
|
9
|
+
};
|
10
|
+
export declare enum MessageType {
|
11
|
+
Auth = 1,
|
12
|
+
Init = 2,
|
13
|
+
Crdt = 3
|
14
|
+
}
|
15
|
+
export type ServerTransportConfig = {
|
16
|
+
reservedLocalEntities: number;
|
17
|
+
networkEntitiesLimit: {
|
18
|
+
serverLimit: number;
|
19
|
+
clientLimit: number;
|
20
|
+
};
|
21
|
+
};
|
22
|
+
declare global {
|
23
|
+
type ClientEvent = {
|
24
|
+
type: 'open';
|
25
|
+
clientId: string;
|
26
|
+
client: {
|
27
|
+
sendCrdtMessage(message: Uint8Array): Promise<void>;
|
28
|
+
getMessages(): Uint8Array[];
|
29
|
+
};
|
30
|
+
} | {
|
31
|
+
type: 'close';
|
32
|
+
clientId: string;
|
33
|
+
};
|
34
|
+
var updateCRDTState: (crdt: Uint8Array) => void;
|
35
|
+
var registerScene: (serverConfig: ServerTransportConfig, fn: (event: ClientEvent) => void) => void;
|
36
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
export var MessageType;
|
2
|
+
(function (MessageType) {
|
3
|
+
MessageType[MessageType["Auth"] = 1] = "Auth";
|
4
|
+
MessageType[MessageType["Init"] = 2] = "Init";
|
5
|
+
MessageType[MessageType["Crdt"] = 3] = "Crdt";
|
6
|
+
})(MessageType || (MessageType = {}));
|
7
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay10cmFuc3BvcnQvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBV0EsTUFBTSxDQUFOLElBQVksV0FJWDtBQUpELFdBQVksV0FBVztJQUNyQiw2Q0FBUSxDQUFBO0lBQ1IsNkNBQVEsQ0FBQTtJQUNSLDZDQUFRLENBQUE7QUFDVixDQUFDLEVBSlcsV0FBVyxLQUFYLFdBQVcsUUFJdEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFbnRpdHksIGVuZ2luZSB9IGZyb20gJ0BkY2wvZWNzJ1xuXG5leHBvcnQgdHlwZSBTb2NrZXQgPSBXZWJTb2NrZXQgJiB7XG4gIGJpbmFyeVR5cGU6IHN0cmluZ1xuICBzZW5kKGRhdGE6IHN0cmluZyB8IFVpbnQ4QXJyYXkpOiB2b2lkXG59XG5cbmV4cG9ydCB0eXBlIE5ldHdvcmtNYW5hZ2VyID0ge1xuICBhZGRFbnRpdHkodGhlRW5naW5lOiB0eXBlb2YgZW5naW5lKTogRW50aXR5XG59XG5cbmV4cG9ydCBlbnVtIE1lc3NhZ2VUeXBlIHtcbiAgQXV0aCA9IDEsXG4gIEluaXQgPSAyLFxuICBDcmR0ID0gM1xufVxuXG5leHBvcnQgdHlwZSBTZXJ2ZXJUcmFuc3BvcnRDb25maWcgPSB7XG4gIHJlc2VydmVkTG9jYWxFbnRpdGllczogbnVtYmVyXG4gIG5ldHdvcmtFbnRpdGllc0xpbWl0OiB7XG4gICAgc2VydmVyTGltaXQ6IG51bWJlclxuICAgIGNsaWVudExpbWl0OiBudW1iZXJcbiAgfVxufVxuXG5kZWNsYXJlIGdsb2JhbCB7XG4gIHR5cGUgQ2xpZW50RXZlbnQgPVxuICAgIHwge1xuICAgICAgICB0eXBlOiAnb3BlbidcbiAgICAgICAgY2xpZW50SWQ6IHN0cmluZ1xuICAgICAgICBjbGllbnQ6IHtcbiAgICAgICAgICBzZW5kQ3JkdE1lc3NhZ2UobWVzc2FnZTogVWludDhBcnJheSk6IFByb21pc2U8dm9pZD5cbiAgICAgICAgICBnZXRNZXNzYWdlcygpOiBVaW50OEFycmF5W11cbiAgICAgICAgfVxuICAgICAgfVxuICAgIHwgeyB0eXBlOiAnY2xvc2UnOyBjbGllbnRJZDogc3RyaW5nIH1cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXZhclxuICB2YXIgdXBkYXRlQ1JEVFN0YXRlOiAoY3JkdDogVWludDhBcnJheSkgPT4gdm9pZFxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdmFyXG4gIHZhciByZWdpc3RlclNjZW5lOiAoc2VydmVyQ29uZmlnOiBTZXJ2ZXJUcmFuc3BvcnRDb25maWcsIGZuOiAoZXZlbnQ6IENsaWVudEV2ZW50KSA9PiB2b2lkKSA9PiB2b2lkXG59XG4iXX0=
|
@@ -0,0 +1,8 @@
|
|
1
|
+
import { TransportMessage } from '@dcl/ecs';
|
2
|
+
import { MessageType } from './types';
|
3
|
+
export declare function encodeString(s: string): Uint8Array;
|
4
|
+
export declare function craftMessage(msgType: MessageType, payload: Uint8Array): Uint8Array;
|
5
|
+
export declare function createNetworkManager(reservedLocalEntities: number, range: [number, number]): {
|
6
|
+
addEntity: () => import("@dcl/ecs").Entity;
|
7
|
+
};
|
8
|
+
export declare function syncFilter(message: Omit<TransportMessage, 'messageBuffer'>): boolean;
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer';
|
2
|
+
import { engine, PointerEventsResult, RESERVED_STATIC_ENTITIES, SyncComponents, CrdtMessageType, EntityUtils, GltfContainerLoadingState } from '@dcl/ecs';
|
3
|
+
import { connected, reservedLocalEntities } from '.';
|
4
|
+
export function encodeString(s) {
|
5
|
+
const buffer = new ReadWriteByteBuffer();
|
6
|
+
buffer.writeUtf8String(s);
|
7
|
+
return buffer.readBuffer();
|
8
|
+
}
|
9
|
+
export function craftMessage(msgType, payload) {
|
10
|
+
const msg = new Uint8Array(payload.byteLength + 1);
|
11
|
+
msg.set([msgType]);
|
12
|
+
msg.set(payload, 1);
|
13
|
+
return msg;
|
14
|
+
}
|
15
|
+
export function createNetworkManager(reservedLocalEntities, range) {
|
16
|
+
return engine.addNetworkManager(reservedLocalEntities, range);
|
17
|
+
}
|
18
|
+
export function syncFilter(message) {
|
19
|
+
if (!connected)
|
20
|
+
return false;
|
21
|
+
const componentId = message.componentId;
|
22
|
+
if ([PointerEventsResult.componentId, GltfContainerLoadingState.componentId].includes(componentId)) {
|
23
|
+
return false;
|
24
|
+
}
|
25
|
+
const [entityId] = EntityUtils.fromEntityId(message.entityId);
|
26
|
+
if (entityId < RESERVED_STATIC_ENTITIES) {
|
27
|
+
return false;
|
28
|
+
}
|
29
|
+
if (entityId < reservedLocalEntities) {
|
30
|
+
return false;
|
31
|
+
}
|
32
|
+
if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
33
|
+
return true;
|
34
|
+
}
|
35
|
+
if (message.timestamp <= 1) {
|
36
|
+
return true;
|
37
|
+
}
|
38
|
+
const sync = SyncComponents.getOrNull(message.entityId);
|
39
|
+
if (!sync)
|
40
|
+
return false;
|
41
|
+
if (message.componentId && sync.componentIds.includes(message.componentId)) {
|
42
|
+
return true;
|
43
|
+
}
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbmV0d29yay10cmFuc3BvcnQvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sd0NBQXdDLENBQUE7QUFDNUUsT0FBTyxFQUNMLE1BQU0sRUFFTixtQkFBbUIsRUFDbkIsd0JBQXdCLEVBQ3hCLGNBQWMsRUFDZCxlQUFlLEVBQ2YsV0FBVyxFQUNYLHlCQUF5QixFQUMxQixNQUFNLFVBQVUsQ0FBQTtBQUVqQixPQUFPLEVBQUUsU0FBUyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sR0FBRyxDQUFBO0FBRXBELE1BQU0sVUFBVSxZQUFZLENBQUMsQ0FBUztJQUNwQyxNQUFNLE1BQU0sR0FBRyxJQUFJLG1CQUFtQixFQUFFLENBQUE7SUFDeEMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUN6QixPQUFPLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQTtBQUM1QixDQUFDO0FBRUQsTUFBTSxVQUFVLFlBQVksQ0FBQyxPQUFvQixFQUFFLE9BQW1CO0lBQ3BFLE1BQU0sR0FBRyxHQUFHLElBQUksVUFBVSxDQUFDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDbEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUE7SUFDbEIsR0FBRyxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUE7SUFDbkIsT0FBTyxHQUFHLENBQUE7QUFDWixDQUFDO0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLHFCQUE2QixFQUFFLEtBQXVCO0lBQ3pGLE9BQU8sTUFBTSxDQUFDLGlCQUFpQixDQUFDLHFCQUFxQixFQUFFLEtBQUssQ0FBQyxDQUFBO0FBQy9ELENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUFDLE9BQWdEO0lBQ3pFLElBQUksQ0FBQyxTQUFTO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDNUIsTUFBTSxXQUFXLEdBQUksT0FBZSxDQUFDLFdBQVcsQ0FBQTtJQUNoRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLHlCQUF5QixDQUFDLFdBQVcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxXQUFXLENBQUMsRUFBRTtRQUNsRyxPQUFPLEtBQUssQ0FBQTtLQUNiO0lBRUQsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLFdBQVcsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRTdELElBQUksUUFBUSxHQUFHLHdCQUF3QixFQUFFO1FBQ3ZDLE9BQU8sS0FBSyxDQUFBO0tBQ2I7SUFFRCxJQUFJLFFBQVEsR0FBRyxxQkFBcUIsRUFBRTtRQUNwQyxPQUFPLEtBQUssQ0FBQTtLQUNiO0lBR0QsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLGVBQWUsQ0FBQyxhQUFhLEVBQUU7UUFDbEQsT0FBTyxJQUFJLENBQUE7S0FDWjtJQUdELElBQUssT0FBZSxDQUFDLFNBQVMsSUFBSSxDQUFDLEVBQUU7UUFDbkMsT0FBTyxJQUFJLENBQUE7S0FDWjtJQUVELE1BQU0sSUFBSSxHQUFHLGNBQWMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ3ZELElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFFdkIsSUFBSyxPQUFlLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFFLE9BQWUsQ0FBQyxXQUFXLENBQUMsRUFBRTtRQUM1RixPQUFPLElBQUksQ0FBQTtLQUNaO0lBRUQsT0FBTyxLQUFLLENBQUE7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgUmVhZFdyaXRlQnl0ZUJ1ZmZlciB9IGZyb20gJ0BkY2wvZWNzL2Rpc3Qvc2VyaWFsaXphdGlvbi9CeXRlQnVmZmVyJ1xuaW1wb3J0IHtcbiAgZW5naW5lLFxuICBUcmFuc3BvcnRNZXNzYWdlLFxuICBQb2ludGVyRXZlbnRzUmVzdWx0LFxuICBSRVNFUlZFRF9TVEFUSUNfRU5USVRJRVMsXG4gIFN5bmNDb21wb25lbnRzLFxuICBDcmR0TWVzc2FnZVR5cGUsXG4gIEVudGl0eVV0aWxzLFxuICBHbHRmQ29udGFpbmVyTG9hZGluZ1N0YXRlXG59IGZyb20gJ0BkY2wvZWNzJ1xuaW1wb3J0IHsgTWVzc2FnZVR5cGUgfSBmcm9tICcuL3R5cGVzJ1xuaW1wb3J0IHsgY29ubmVjdGVkLCByZXNlcnZlZExvY2FsRW50aXRpZXMgfSBmcm9tICcuJ1xuXG5leHBvcnQgZnVuY3Rpb24gZW5jb2RlU3RyaW5nKHM6IHN0cmluZyk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBidWZmZXIgPSBuZXcgUmVhZFdyaXRlQnl0ZUJ1ZmZlcigpXG4gIGJ1ZmZlci53cml0ZVV0ZjhTdHJpbmcocylcbiAgcmV0dXJuIGJ1ZmZlci5yZWFkQnVmZmVyKClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyYWZ0TWVzc2FnZShtc2dUeXBlOiBNZXNzYWdlVHlwZSwgcGF5bG9hZDogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCBtc2cgPSBuZXcgVWludDhBcnJheShwYXlsb2FkLmJ5dGVMZW5ndGggKyAxKVxuICBtc2cuc2V0KFttc2dUeXBlXSlcbiAgbXNnLnNldChwYXlsb2FkLCAxKVxuICByZXR1cm4gbXNnXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVOZXR3b3JrTWFuYWdlcihyZXNlcnZlZExvY2FsRW50aXRpZXM6IG51bWJlciwgcmFuZ2U6IFtudW1iZXIsIG51bWJlcl0pIHtcbiAgcmV0dXJuIGVuZ2luZS5hZGROZXR3b3JrTWFuYWdlcihyZXNlcnZlZExvY2FsRW50aXRpZXMsIHJhbmdlKVxufVxuXG5leHBvcnQgZnVuY3Rpb24gc3luY0ZpbHRlcihtZXNzYWdlOiBPbWl0PFRyYW5zcG9ydE1lc3NhZ2UsICdtZXNzYWdlQnVmZmVyJz4pIHtcbiAgaWYgKCFjb25uZWN0ZWQpIHJldHVybiBmYWxzZVxuICBjb25zdCBjb21wb25lbnRJZCA9IChtZXNzYWdlIGFzIGFueSkuY29tcG9uZW50SWRcbiAgaWYgKFtQb2ludGVyRXZlbnRzUmVzdWx0LmNvbXBvbmVudElkLCBHbHRmQ29udGFpbmVyTG9hZGluZ1N0YXRlLmNvbXBvbmVudElkXS5pbmNsdWRlcyhjb21wb25lbnRJZCkpIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuXG4gIGNvbnN0IFtlbnRpdHlJZF0gPSBFbnRpdHlVdGlscy5mcm9tRW50aXR5SWQobWVzc2FnZS5lbnRpdHlJZClcbiAgLy8gZmlsdGVyIG1lc3NhZ2VzIGZyb20gcmVzZXJ2ZWQgZW50aXRpZXMuXG4gIGlmIChlbnRpdHlJZCA8IFJFU0VSVkVEX1NUQVRJQ19FTlRJVElFUykge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG5cbiAgaWYgKGVudGl0eUlkIDwgcmVzZXJ2ZWRMb2NhbEVudGl0aWVzKSB7XG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cblxuICAvLyBOZXR3b3JrIEVudGl0eSBBbHdheXNcbiAgaWYgKG1lc3NhZ2UudHlwZSA9PT0gQ3JkdE1lc3NhZ2VUeXBlLkRFTEVURV9FTlRJVFkpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLy8gVEJEOiBGaXJzdCBjb21wb25lbnRcbiAgaWYgKChtZXNzYWdlIGFzIGFueSkudGltZXN0YW1wIDw9IDEpIHtcbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY29uc3Qgc3luYyA9IFN5bmNDb21wb25lbnRzLmdldE9yTnVsbChtZXNzYWdlLmVudGl0eUlkKVxuICBpZiAoIXN5bmMpIHJldHVybiBmYWxzZVxuXG4gIGlmICgobWVzc2FnZSBhcyBhbnkpLmNvbXBvbmVudElkICYmIHN5bmMuY29tcG9uZW50SWRzLmluY2x1ZGVzKChtZXNzYWdlIGFzIGFueSkuY29tcG9uZW50SWQpKSB7XG4gICAgcmV0dXJuIHRydWVcbiAgfVxuXG4gIHJldHVybiBmYWxzZVxufVxuIl19
|
package/package.json
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
{
|
2
2
|
"name": "@dcl/sdk",
|
3
3
|
"description": "",
|
4
|
-
"version": "7.3.15-
|
4
|
+
"version": "7.3.15-6201550692.commit-88f3deb",
|
5
5
|
"author": "Decentraland",
|
6
6
|
"dependencies": {
|
7
|
-
"@dcl/ecs": "7.3.15-
|
7
|
+
"@dcl/ecs": "7.3.15-6201550692.commit-88f3deb",
|
8
8
|
"@dcl/ecs-math": "2.0.2",
|
9
9
|
"@dcl/explorer": "1.0.143989-20230907142850.commit-0c0a775",
|
10
|
-
"@dcl/js-runtime": "7.3.15-
|
11
|
-
"@dcl/react-ecs": "7.3.15-
|
12
|
-
"@dcl/sdk-commands": "7.3.15-
|
10
|
+
"@dcl/js-runtime": "7.3.15-6201550692.commit-88f3deb",
|
11
|
+
"@dcl/react-ecs": "7.3.15-6201550692.commit-88f3deb",
|
12
|
+
"@dcl/sdk-commands": "7.3.15-6201550692.commit-88f3deb"
|
13
13
|
},
|
14
14
|
"keywords": [],
|
15
15
|
"license": "Apache-2.0",
|
@@ -34,5 +34,5 @@
|
|
34
34
|
},
|
35
35
|
"types": "./index.d.ts",
|
36
36
|
"typings": "./index.d.ts",
|
37
|
-
"commit": "
|
37
|
+
"commit": "88f3deb16cd7fc345e46909f0772eefe9b1b5975"
|
38
38
|
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { IEngine, CrdtMessage, CrdtMessageType } from '@dcl/ecs'
|
2
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
|
3
|
+
import { readMessage } from '@dcl/ecs/dist/serialization/crdt/message'
|
4
|
+
|
5
|
+
export function* serializeCrdtMessages(prefix: string, data: Uint8Array, engine: IEngine) {
|
6
|
+
const buffer = new ReadWriteByteBuffer(data)
|
7
|
+
|
8
|
+
let message: CrdtMessage | null
|
9
|
+
|
10
|
+
while ((message = readMessage(buffer))) {
|
11
|
+
const ent = `0x${message.entityId.toString(16)}`
|
12
|
+
const preface = `${prefix}: ${CrdtMessageType[message.type]} e=${ent}`
|
13
|
+
if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
14
|
+
yield `${preface}`
|
15
|
+
}
|
16
|
+
|
17
|
+
if (
|
18
|
+
message.type === CrdtMessageType.PUT_COMPONENT ||
|
19
|
+
message.type === CrdtMessageType.DELETE_COMPONENT ||
|
20
|
+
message.type === CrdtMessageType.APPEND_VALUE
|
21
|
+
) {
|
22
|
+
const { componentId, timestamp } = message
|
23
|
+
const data = 'data' in message ? message.data : undefined
|
24
|
+
|
25
|
+
try {
|
26
|
+
const c = engine.getComponent(componentId)
|
27
|
+
|
28
|
+
yield `${preface} c=${c.componentName} t=${timestamp} data=${JSON.stringify(
|
29
|
+
(data && c.schema.deserialize(new ReadWriteByteBuffer(data))) || null
|
30
|
+
)}`
|
31
|
+
} catch {
|
32
|
+
yield `${preface} c=${componentId} t=${timestamp} data=?`
|
33
|
+
}
|
34
|
+
} else if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
35
|
+
yield preface
|
36
|
+
} else {
|
37
|
+
yield `${preface} Unknown CrdtMessageType`
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
@@ -0,0 +1,74 @@
|
|
1
|
+
import { craftMessage, createNetworkManager, encodeString, syncFilter } from './utils'
|
2
|
+
import { Transport, engine } from '@dcl/ecs'
|
3
|
+
import { getHeaders } from '~system/SignedFetch'
|
4
|
+
|
5
|
+
import { MessageType, NetworkManager, Socket } from './types'
|
6
|
+
|
7
|
+
export type ClientTransportConfig = {
|
8
|
+
serverUrl: string
|
9
|
+
}
|
10
|
+
|
11
|
+
export async function createClientTransport({ serverUrl }: ClientTransportConfig): Promise<NetworkManager> {
|
12
|
+
const messagesToProcess: Uint8Array[] = []
|
13
|
+
|
14
|
+
return new Promise<NetworkManager>((resolve, reject) => {
|
15
|
+
try {
|
16
|
+
const ws = new WebSocket(serverUrl) as Socket
|
17
|
+
ws.binaryType = 'arraybuffer'
|
18
|
+
|
19
|
+
ws.onopen = async () => {
|
20
|
+
console.log('WS Server Sync connected')
|
21
|
+
const { headers } = await getHeaders({ url: serverUrl, init: { headers: {} } })
|
22
|
+
ws.send(craftMessage(MessageType.Auth, encodeString(JSON.stringify(headers))))
|
23
|
+
|
24
|
+
const transport: Transport = {
|
25
|
+
filter: syncFilter,
|
26
|
+
send: async (message: Uint8Array) => {
|
27
|
+
if (ws.readyState === WebSocket.OPEN) {
|
28
|
+
ws.send(craftMessage(MessageType.Crdt, message))
|
29
|
+
}
|
30
|
+
if (messagesToProcess && messagesToProcess.length) {
|
31
|
+
if (transport.onmessage) {
|
32
|
+
for (const byteArray of messagesToProcess) {
|
33
|
+
transport.onmessage(byteArray)
|
34
|
+
}
|
35
|
+
}
|
36
|
+
}
|
37
|
+
messagesToProcess.length = 0
|
38
|
+
}
|
39
|
+
}
|
40
|
+
engine.addTransport(transport)
|
41
|
+
}
|
42
|
+
|
43
|
+
ws.onmessage = (event) => {
|
44
|
+
if (event.data.byteLength) {
|
45
|
+
let offset = 0
|
46
|
+
const r = new Uint8Array(event.data)
|
47
|
+
const view = new DataView(r.buffer)
|
48
|
+
const msgType = view.getUint8(offset)
|
49
|
+
offset += 1
|
50
|
+
|
51
|
+
if (msgType === MessageType.Crdt) {
|
52
|
+
messagesToProcess.push(r.subarray(offset))
|
53
|
+
} else if (msgType === MessageType.Init) {
|
54
|
+
const start = view.getUint32(offset)
|
55
|
+
offset += 4
|
56
|
+
const size = view.getUint32(offset)
|
57
|
+
offset += 4
|
58
|
+
const localEntitiesReserved = view.getUint32(offset)
|
59
|
+
offset += 4
|
60
|
+
resolve(createNetworkManager(localEntitiesReserved, [start, start + size]))
|
61
|
+
messagesToProcess.push(r.subarray(offset))
|
62
|
+
}
|
63
|
+
}
|
64
|
+
}
|
65
|
+
|
66
|
+
ws.onerror = (e) => {
|
67
|
+
console.error(e)
|
68
|
+
reject(e)
|
69
|
+
}
|
70
|
+
} catch (err) {
|
71
|
+
reject(err)
|
72
|
+
}
|
73
|
+
})
|
74
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { isServer } from '~system/EngineApi'
|
2
|
+
|
3
|
+
import { NetworkManager, ServerTransportConfig } from './types'
|
4
|
+
import { Schemas, engine } from '@dcl/ecs'
|
5
|
+
import { createServerTransport } from './server'
|
6
|
+
import { ClientTransportConfig, createClientTransport } from './client'
|
7
|
+
|
8
|
+
export { NetworkManager } from './types'
|
9
|
+
|
10
|
+
export type NetworkTransportConfig = ClientTransportConfig & Partial<ServerTransportConfig>
|
11
|
+
|
12
|
+
export let connected = false
|
13
|
+
|
14
|
+
const DEFAULT_NETWORK_ENTITY_LIMIT_SERVER = 512
|
15
|
+
const DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT = 100
|
16
|
+
const DEFAULT_RESERVED_LOCAL_ENTITIES = 2560
|
17
|
+
|
18
|
+
export let reservedLocalEntities: number
|
19
|
+
/**
|
20
|
+
* @alpha
|
21
|
+
* Connect to CRDT server
|
22
|
+
*/
|
23
|
+
export async function createNetworkManager(config: NetworkTransportConfig): Promise<NetworkManager> {
|
24
|
+
if (connected) {
|
25
|
+
throw new Error('Transport is already created')
|
26
|
+
}
|
27
|
+
|
28
|
+
const serverConfig = {
|
29
|
+
networkEntitiesLimit: config.networkEntitiesLimit ?? {
|
30
|
+
serverLimit: DEFAULT_NETWORK_ENTITY_LIMIT_SERVER,
|
31
|
+
clientLimit: DEFAULT_NETWORK_ENTITY_LIMIT_CLIENT
|
32
|
+
},
|
33
|
+
reservedLocalEntities: config.reservedLocalEntities || DEFAULT_RESERVED_LOCAL_ENTITIES
|
34
|
+
}
|
35
|
+
reservedLocalEntities = serverConfig.reservedLocalEntities
|
36
|
+
|
37
|
+
const networkFactory =
|
38
|
+
isServer && (await isServer({})).isServer ? createServerTransport(serverConfig) : createClientTransport(config)
|
39
|
+
connected = true
|
40
|
+
return networkFactory
|
41
|
+
}
|
42
|
+
|
43
|
+
export const PlayersConnected = engine.defineComponent('chore:network:players', {
|
44
|
+
usersId: Schemas.Array(Schemas.String)
|
45
|
+
})
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import { engine, SyncComponents, Transport } from '@dcl/ecs'
|
2
|
+
import { engineToCrdt } from './state'
|
3
|
+
import { syncFilter, createNetworkManager } from './utils'
|
4
|
+
import { NetworkManager, ServerTransportConfig } from './types'
|
5
|
+
import { PlayersConnected } from '.'
|
6
|
+
|
7
|
+
export async function createServerTransport(config: ServerTransportConfig): Promise<NetworkManager> {
|
8
|
+
const connectedClients = new Set<string>()
|
9
|
+
engine.addTransport({
|
10
|
+
send: async (message) => {
|
11
|
+
if (message.byteLength) {
|
12
|
+
globalThis.updateCRDTState(engineToCrdt(engine))
|
13
|
+
}
|
14
|
+
},
|
15
|
+
filter: syncFilter
|
16
|
+
})
|
17
|
+
|
18
|
+
let time = 0
|
19
|
+
function initialCrdtState(dt: number) {
|
20
|
+
time += dt
|
21
|
+
if (time >= 1) {
|
22
|
+
globalThis.updateCRDTState(engineToCrdt(engine))
|
23
|
+
engine.removeSystem(initialCrdtState)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
engine.addSystem(initialCrdtState)
|
28
|
+
globalThis.registerScene(config, (event) => {
|
29
|
+
const { type } = event
|
30
|
+
if (type === 'open') {
|
31
|
+
const { clientId, client } = event
|
32
|
+
const transport: Transport = {
|
33
|
+
filter: (message) => {
|
34
|
+
if (!connectedClients.has(clientId)) return false
|
35
|
+
return syncFilter(message)
|
36
|
+
},
|
37
|
+
send: async (message) => {
|
38
|
+
if (message.byteLength > 0) {
|
39
|
+
await client.sendCrdtMessage(message)
|
40
|
+
}
|
41
|
+
|
42
|
+
if (transport.onmessage) {
|
43
|
+
const messages = client.getMessages()
|
44
|
+
for (const byteArray of messages) {
|
45
|
+
transport.onmessage(byteArray)
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
engine.addTransport(transport)
|
52
|
+
connectedClients.add(event.clientId)
|
53
|
+
} else if (type === 'close') {
|
54
|
+
connectedClients.delete(event.clientId)
|
55
|
+
}
|
56
|
+
PlayersConnected.createOrReplace(players, { usersId: [...connectedClients.values()].map(String) })
|
57
|
+
})
|
58
|
+
|
59
|
+
const networkEntityFactory = createNetworkManager(config.reservedLocalEntities, [
|
60
|
+
config.reservedLocalEntities,
|
61
|
+
config.reservedLocalEntities + config.networkEntitiesLimit.serverLimit
|
62
|
+
])
|
63
|
+
const players = networkEntityFactory.addEntity()
|
64
|
+
SyncComponents.create(players, { componentIds: [PlayersConnected.componentId] })
|
65
|
+
return networkEntityFactory
|
66
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
|
2
|
+
import { IEngine, SyncComponents } from '@dcl/ecs'
|
3
|
+
|
4
|
+
export function engineToCrdt(engine: IEngine): Uint8Array {
|
5
|
+
const crdtBuffer = new ReadWriteByteBuffer()
|
6
|
+
const syncEntities = new Set(Array.from(engine.getEntitiesWith(SyncComponents)).map(($) => $[0]))
|
7
|
+
|
8
|
+
for (const itComponentDefinition of engine.componentsIter()) {
|
9
|
+
itComponentDefinition.dumpCrdtStateToBuffer(crdtBuffer, (entity) => syncEntities.has(entity))
|
10
|
+
}
|
11
|
+
|
12
|
+
return crdtBuffer.toBinary()
|
13
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Entity, engine } from '@dcl/ecs'
|
2
|
+
|
3
|
+
export type Socket = WebSocket & {
|
4
|
+
binaryType: string
|
5
|
+
send(data: string | Uint8Array): void
|
6
|
+
}
|
7
|
+
|
8
|
+
export type NetworkManager = {
|
9
|
+
addEntity(theEngine: typeof engine): Entity
|
10
|
+
}
|
11
|
+
|
12
|
+
export enum MessageType {
|
13
|
+
Auth = 1,
|
14
|
+
Init = 2,
|
15
|
+
Crdt = 3
|
16
|
+
}
|
17
|
+
|
18
|
+
export type ServerTransportConfig = {
|
19
|
+
reservedLocalEntities: number
|
20
|
+
networkEntitiesLimit: {
|
21
|
+
serverLimit: number
|
22
|
+
clientLimit: number
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
declare global {
|
27
|
+
type ClientEvent =
|
28
|
+
| {
|
29
|
+
type: 'open'
|
30
|
+
clientId: string
|
31
|
+
client: {
|
32
|
+
sendCrdtMessage(message: Uint8Array): Promise<void>
|
33
|
+
getMessages(): Uint8Array[]
|
34
|
+
}
|
35
|
+
}
|
36
|
+
| { type: 'close'; clientId: string }
|
37
|
+
// eslint-disable-next-line no-var
|
38
|
+
var updateCRDTState: (crdt: Uint8Array) => void
|
39
|
+
// eslint-disable-next-line no-var
|
40
|
+
var registerScene: (serverConfig: ServerTransportConfig, fn: (event: ClientEvent) => void) => void
|
41
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { ReadWriteByteBuffer } from '@dcl/ecs/dist/serialization/ByteBuffer'
|
2
|
+
import {
|
3
|
+
engine,
|
4
|
+
TransportMessage,
|
5
|
+
PointerEventsResult,
|
6
|
+
RESERVED_STATIC_ENTITIES,
|
7
|
+
SyncComponents,
|
8
|
+
CrdtMessageType,
|
9
|
+
EntityUtils,
|
10
|
+
GltfContainerLoadingState
|
11
|
+
} from '@dcl/ecs'
|
12
|
+
import { MessageType } from './types'
|
13
|
+
import { connected, reservedLocalEntities } from '.'
|
14
|
+
|
15
|
+
export function encodeString(s: string): Uint8Array {
|
16
|
+
const buffer = new ReadWriteByteBuffer()
|
17
|
+
buffer.writeUtf8String(s)
|
18
|
+
return buffer.readBuffer()
|
19
|
+
}
|
20
|
+
|
21
|
+
export function craftMessage(msgType: MessageType, payload: Uint8Array): Uint8Array {
|
22
|
+
const msg = new Uint8Array(payload.byteLength + 1)
|
23
|
+
msg.set([msgType])
|
24
|
+
msg.set(payload, 1)
|
25
|
+
return msg
|
26
|
+
}
|
27
|
+
|
28
|
+
export function createNetworkManager(reservedLocalEntities: number, range: [number, number]) {
|
29
|
+
return engine.addNetworkManager(reservedLocalEntities, range)
|
30
|
+
}
|
31
|
+
|
32
|
+
export function syncFilter(message: Omit<TransportMessage, 'messageBuffer'>) {
|
33
|
+
if (!connected) return false
|
34
|
+
const componentId = (message as any).componentId
|
35
|
+
if ([PointerEventsResult.componentId, GltfContainerLoadingState.componentId].includes(componentId)) {
|
36
|
+
return false
|
37
|
+
}
|
38
|
+
|
39
|
+
const [entityId] = EntityUtils.fromEntityId(message.entityId)
|
40
|
+
// filter messages from reserved entities.
|
41
|
+
if (entityId < RESERVED_STATIC_ENTITIES) {
|
42
|
+
return false
|
43
|
+
}
|
44
|
+
|
45
|
+
if (entityId < reservedLocalEntities) {
|
46
|
+
return false
|
47
|
+
}
|
48
|
+
|
49
|
+
// Network Entity Always
|
50
|
+
if (message.type === CrdtMessageType.DELETE_ENTITY) {
|
51
|
+
return true
|
52
|
+
}
|
53
|
+
|
54
|
+
// TBD: First component
|
55
|
+
if ((message as any).timestamp <= 1) {
|
56
|
+
return true
|
57
|
+
}
|
58
|
+
|
59
|
+
const sync = SyncComponents.getOrNull(message.entityId)
|
60
|
+
if (!sync) return false
|
61
|
+
|
62
|
+
if ((message as any).componentId && sync.componentIds.includes((message as any).componentId)) {
|
63
|
+
return true
|
64
|
+
}
|
65
|
+
|
66
|
+
return false
|
67
|
+
}
|