@dcl/sdk 7.3.31-7169243942.commit-5f044c6 → 7.3.32-7170667436.commit-11a2181
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.js +7 -4
- package/internal/transports/rendererTransport.js +3 -2
- package/message-bus.js +8 -6
- package/network/binary-message-bus.d.ts +18 -0
- package/network/binary-message-bus.js +68 -0
- package/network/entities.d.ts +11 -0
- package/network/entities.js +77 -0
- package/network/filter.d.ts +2 -0
- package/network/filter.js +37 -0
- package/network/index.d.ts +2 -0
- package/network/index.js +7 -0
- package/network/message-bus-sync.d.ts +17 -0
- package/network/message-bus-sync.js +52 -0
- package/network/state.js +39 -0
- package/network/utils.d.ts +18 -0
- package/network/utils.js +69 -0
- package/package.json +6 -6
- package/src/internal/transports/logger.ts +9 -4
- package/src/internal/transports/rendererTransport.ts +2 -1
- package/src/message-bus.ts +7 -9
- package/src/network/README.md +122 -0
- package/src/network/binary-message-bus.ts +72 -0
- package/src/network/entities.ts +132 -0
- package/src/network/filter.ts +64 -0
- package/src/network/index.ts +13 -0
- package/src/network/message-bus-sync.ts +97 -0
- package/src/network/state.ts +65 -0
- package/src/network/utils.ts +145 -0
- package/network-transport/client.d.ts +0 -5
- package/network-transport/client.js +0 -68
- package/network-transport/index.d.ts +0 -10
- package/network-transport/index.js +0 -29
- package/network-transport/server.d.ts +0 -2
- package/network-transport/server.js +0 -62
- package/network-transport/state.js +0 -11
- package/network-transport/types.d.ts +0 -36
- package/network-transport/types.js +0 -7
- package/network-transport/utils.d.ts +0 -8
- package/network-transport/utils.js +0 -46
- package/src/network-transport/client.ts +0 -77
- package/src/network-transport/index.ts +0 -45
- package/src/network-transport/server.ts +0 -66
- package/src/network-transport/state.ts +0 -13
- package/src/network-transport/types.ts +0 -41
- package/src/network-transport/utils.ts +0 -67
- /package/{network-transport → network}/state.d.ts +0 -0
@@ -1,77 +0,0 @@
|
|
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
|
-
ws.onclose = () => {
|
71
|
-
reject(new Error('socket closed'))
|
72
|
-
}
|
73
|
-
} catch (err) {
|
74
|
-
reject(err)
|
75
|
-
}
|
76
|
-
})
|
77
|
-
}
|
@@ -1,45 +0,0 @@
|
|
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
|
-
})
|
@@ -1,66 +0,0 @@
|
|
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
|
-
}
|
@@ -1,13 +0,0 @@
|
|
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
|
-
}
|
@@ -1,41 +0,0 @@
|
|
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
|
-
}
|
@@ -1,67 +0,0 @@
|
|
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
|
-
}
|
File without changes
|