@crowdedkingdoms/crowdyjs 15.4.2 → 15.5.0-test.1
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/README.md +15 -2
- package/dist/binary-wire.d.ts +10 -0
- package/dist/binary-wire.d.ts.map +1 -1
- package/dist/binary-wire.js +27 -0
- package/dist/default-origin.d.ts +6 -6
- package/dist/default-origin.js +6 -6
- package/dist/domains/udp.d.ts +47 -1
- package/dist/domains/udp.d.ts.map +1 -1
- package/dist/domains/udp.js +59 -2
- package/dist/generated/graphql.d.ts +172 -37
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +11 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/kit/npcs.d.ts.map +1 -1
- package/dist/kit/social.d.ts.map +1 -1
- package/dist/media/video-frames.d.ts +106 -0
- package/dist/media/video-frames.d.ts.map +1 -0
- package/dist/media/video-frames.js +215 -0
- package/dist/metrics.d.ts +1 -1
- package/dist/metrics.js +2 -2
- package/dist/realtime.d.ts +16 -0
- package/dist/realtime.d.ts.map +1 -1
- package/dist/realtime.js +8 -0
- package/dist/stores/actors.d.ts +15 -0
- package/dist/stores/actors.d.ts.map +1 -1
- package/dist/stores/actors.js +41 -0
- package/dist/stores/session.d.ts +1 -1
- package/dist/stores/session.d.ts.map +1 -1
- package/dist/stores/session.js +2 -0
- package/dist/types.d.ts +88 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -174,7 +174,7 @@ never told about, so a native refresh without it is a re-placement.
|
|
|
174
174
|
— `appId` is **required** (the SDK opens the realtime socket on demand and
|
|
175
175
|
scopes it to that app).
|
|
176
176
|
4. Join a chunk by sending an initial actor update.
|
|
177
|
-
5. Send actor, voxel, text, audio, and client-event updates through `game.udp`
|
|
177
|
+
5. Send actor, voxel, text, audio, video, and client-event updates through `game.udp`
|
|
178
178
|
or the higher-level `game.world(appId)` helpers.
|
|
179
179
|
6. Before the app token expires, call `game.refreshGameplayToken()`.
|
|
180
180
|
7. Call `client.close()` (and `game.close()`) when disposing the SDK instances.
|
|
@@ -203,7 +203,7 @@ never told about, so a native refresh without it is a re-placement.
|
|
|
203
203
|
| `client.marketplace` | Player-code store/install/consent flows plus player-authorized grid claims (`claimGridOwnership`, `claimGridChunk`, `releaseClaimedGrid`) and client-mod artifact fetches. |
|
|
204
204
|
| `client.crowdyStudio` | Cloud project, personal-library, and common-file APIs for Crowdy Studio: target-scoped files, metadata/module names, optimistic revisions, copy-by-value imports, atomic saves. |
|
|
205
205
|
| `client.crowdyStudioAgent` | Generated, app-token Game API transport for durable agent sessions: history/session pages, descriptors/budgets, approvals, tool results, heartbeat, control mutations, ordered event subscriptions. |
|
|
206
|
-
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendTextPacket`, `sendClientEvent`, `sendSingleActorMessage`, `sendChannelMessage`). |
|
|
206
|
+
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendVideoPacket` / `sendVideoFrame`, `sendTextPacket`, `sendClientEvent`, `sendSingleActorMessage`, `sendChannelMessage`). |
|
|
207
207
|
| `client.realtime` | Connection status, manual `connect()` / `disconnect()`, `onStatus()` listener. |
|
|
208
208
|
| `client.refreshGameplayToken()` | Safely rotates an active game client's app token (see [Token refresh](#token-refresh-during-gameplay)). |
|
|
209
209
|
| `client.world(appId)` | Higher-level helpers for browser games (`actor.join`, `actor.sendState`, `actor.sendText`, `actor.sendToActor`). |
|
|
@@ -287,6 +287,16 @@ const unsubscribe = client.udp.subscribe(
|
|
|
287
287
|
voxelUpdate: (event) => { /* ... */ },
|
|
288
288
|
text: (event) => { /* ... */ },
|
|
289
289
|
audio: (event) => { /* ... */ },
|
|
290
|
+
video: (event) => {
|
|
291
|
+
// One webcam fragment; feed a VideoFrameAssembler to get whole frames.
|
|
292
|
+
const frame = assembler.ingest(event.uuid, decodeBase64(event.videoData));
|
|
293
|
+
if (frame) drawJpeg(event.uuid, frame.bytes);
|
|
294
|
+
},
|
|
295
|
+
actorLeft: (event) => {
|
|
296
|
+
// The server says this actor is gone (about 5 s after its last update).
|
|
297
|
+
// World Stores do this for you: `session.actors.onLeave` fires at once.
|
|
298
|
+
removeAvatar(event.uuid);
|
|
299
|
+
},
|
|
290
300
|
clientEvent: (event) => { /* ... */ },
|
|
291
301
|
serverEvent: (event) => { /* ... */ },
|
|
292
302
|
singleActorMessage: (event) => {
|
|
@@ -460,6 +470,9 @@ session.self.patchState({ x: 12.5, yaw: 1.57 });
|
|
|
460
470
|
console.log(session.self.status, session.self.lastAck?.state);
|
|
461
471
|
|
|
462
472
|
// Everyone else: typed, self-filtered, staleness-managed — render from it.
|
|
473
|
+
// A departure the server announces (ActorLeftNotification, Buddy v0.25.0)
|
|
474
|
+
// removes the actor and fires `onLeave` immediately; the 12 s reaper is the
|
|
475
|
+
// fallback for a lost datagram. A later update for the same uuid is a rejoin.
|
|
463
476
|
for (const actor of session.actors.list()) {
|
|
464
477
|
render(actor.uuid, actor.state, actor.samples); // samples → interpolation
|
|
465
478
|
}
|
package/dist/binary-wire.d.ts
CHANGED
|
@@ -34,6 +34,9 @@ export declare const WireMessageType: {
|
|
|
34
34
|
readonly CLIENT_EVENT_NOTIFICATION_2: 138;
|
|
35
35
|
readonly SERVER_EVENT_NOTIFICATION_2: 139;
|
|
36
36
|
readonly SINGLE_ACTOR_MESSAGE: 142;
|
|
37
|
+
readonly CLIENT_VIDEO_PACKET_2: 143;
|
|
38
|
+
readonly CLIENT_VIDEO_NOTIFICATION_2: 144;
|
|
39
|
+
readonly ACTOR_LEFT_NOTIFICATION_2: 145;
|
|
37
40
|
};
|
|
38
41
|
/**
|
|
39
42
|
* Per-session signing context: the game token id (from the relay `ready`
|
|
@@ -73,6 +76,13 @@ export declare function serializeVoxelUpdate(ctx: RelaySignContext, input: Spati
|
|
|
73
76
|
export declare function serializeAudioPacket(ctx: RelaySignContext, input: SpatialSendBase & {
|
|
74
77
|
audioData: string;
|
|
75
78
|
}): Promise<Uint8Array>;
|
|
79
|
+
/**
|
|
80
|
+
* One video FRAGMENT (header + body slice from `fragmentFrame`) as a 143 datagram.
|
|
81
|
+
* Defaults match audio: `distance` 1, `decayRate` 0.
|
|
82
|
+
*/
|
|
83
|
+
export declare function serializeVideoPacket(ctx: RelaySignContext, input: SpatialSendBase & {
|
|
84
|
+
videoData: string;
|
|
85
|
+
}): Promise<Uint8Array>;
|
|
76
86
|
export declare function serializeTextPacket(ctx: RelaySignContext, input: SpatialSendBase & {
|
|
77
87
|
text: string;
|
|
78
88
|
}): Promise<Uint8Array>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"binary-wire.d.ts","sourceRoot":"","sources":["../src/binary-wire.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C,kEAAkE;AAClE,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"binary-wire.d.ts","sourceRoot":"","sources":["../src/binary-wire.ts"],"names":[],"mappings":"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"}
|
package/dist/binary-wire.js
CHANGED
|
@@ -34,6 +34,11 @@ export const WireMessageType = {
|
|
|
34
34
|
CLIENT_EVENT_NOTIFICATION_2: 138,
|
|
35
35
|
SERVER_EVENT_NOTIFICATION_2: 139,
|
|
36
36
|
SINGLE_ACTOR_MESSAGE: 142,
|
|
37
|
+
// Buddy v0.25.0: webcam video pair (audio's shape, payload = one SDK
|
|
38
|
+
// fragment, see media/video-frames.ts) and the server-only actor-left downlink.
|
|
39
|
+
CLIENT_VIDEO_PACKET_2: 143,
|
|
40
|
+
CLIENT_VIDEO_NOTIFICATION_2: 144,
|
|
41
|
+
ACTOR_LEFT_NOTIFICATION_2: 145,
|
|
37
42
|
};
|
|
38
43
|
const SPATIAL_HEADER_SIZE = 68;
|
|
39
44
|
const UUID_SIZE = 32;
|
|
@@ -174,6 +179,13 @@ export function serializeVoxelUpdate(ctx, input) {
|
|
|
174
179
|
export function serializeAudioPacket(ctx, input) {
|
|
175
180
|
return serializeSpatial(ctx, WireMessageType.CLIENT_AUDIO_PACKET_2, input.appId, input.chunk, input.distance ?? 1, input.decayRate ?? 0, input.uuid, decodeBase64(input.audioData ?? ''), input.sequenceNumber ?? 0);
|
|
176
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* One video FRAGMENT (header + body slice from `fragmentFrame`) as a 143 datagram.
|
|
184
|
+
* Defaults match audio: `distance` 1, `decayRate` 0.
|
|
185
|
+
*/
|
|
186
|
+
export function serializeVideoPacket(ctx, input) {
|
|
187
|
+
return serializeSpatial(ctx, WireMessageType.CLIENT_VIDEO_PACKET_2, input.appId, input.chunk, input.distance ?? 1, input.decayRate ?? 0, input.uuid, decodeBase64(input.videoData ?? ''), input.sequenceNumber ?? 0);
|
|
188
|
+
}
|
|
177
189
|
export function serializeTextPacket(ctx, input) {
|
|
178
190
|
return serializeSpatial(ctx, WireMessageType.CLIENT_TEXT_PACKET_2, input.appId, input.chunk, input.distance ?? 8, input.decayRate ?? 0, input.uuid, textEncoder.encode(input.text ?? ''), input.sequenceNumber ?? 0);
|
|
179
191
|
}
|
|
@@ -375,6 +387,21 @@ function parseOne(bytes) {
|
|
|
375
387
|
...spatialCommon(p),
|
|
376
388
|
audioData: encodeBase64(p.payload),
|
|
377
389
|
};
|
|
390
|
+
case WireMessageType.CLIENT_VIDEO_NOTIFICATION_2:
|
|
391
|
+
return {
|
|
392
|
+
__typename: 'ClientVideoNotification',
|
|
393
|
+
...spatialCommon(p),
|
|
394
|
+
videoData: encodeBase64(p.payload),
|
|
395
|
+
};
|
|
396
|
+
case WireMessageType.ACTOR_LEFT_NOTIFICATION_2: {
|
|
397
|
+
// [1B reason]; anything but 1 reads as STALE (0) per the contract.
|
|
398
|
+
const { decayRate: _r, ...rest } = spatialCommon(p);
|
|
399
|
+
return {
|
|
400
|
+
__typename: 'ActorLeftNotification',
|
|
401
|
+
...rest,
|
|
402
|
+
leftReason: p.payload.length >= 1 && p.payload[0] === 1 ? 1 : 0,
|
|
403
|
+
};
|
|
404
|
+
}
|
|
378
405
|
case WireMessageType.CLIENT_TEXT_NOTIFICATION_2:
|
|
379
406
|
return {
|
|
380
407
|
__typename: 'ClientTextNotification',
|
package/dist/default-origin.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED — do not edit. The operator tooling's
|
|
3
|
-
* `sync-client-origins.mjs --write --tier
|
|
3
|
+
* `sync-client-origins.mjs --write --tier test` writes this file, and
|
|
4
4
|
* `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
|
|
5
5
|
* host that declaration does not carry. Regenerate; never hand-edit.
|
|
6
6
|
*
|
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
* than no default at all. Every fallback this SDK ever removed named a host that
|
|
11
11
|
* was already dead. A generated file plus a gate is what makes this one different.
|
|
12
12
|
*
|
|
13
|
-
* Source: the operator's per-tier public CK API origin declaration, tier '
|
|
13
|
+
* Source: the operator's per-tier public CK API origin declaration, tier 'test'
|
|
14
14
|
*/
|
|
15
15
|
/** The tier this build of the SDK is published for. */
|
|
16
|
-
export declare const CROWDY_DEFAULT_TIER = "
|
|
16
|
+
export declare const CROWDY_DEFAULT_TIER = "test";
|
|
17
17
|
/** The public CK API origin for that tier. */
|
|
18
|
-
export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.
|
|
18
|
+
export declare const CROWDY_DEFAULT_HTTP_ORIGIN = "https://ck.test.crowdedkingdoms.com";
|
|
19
19
|
/** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
|
|
20
|
-
export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.
|
|
20
|
+
export declare const CROWDY_DEFAULT_WS_ORIGIN = "wss://ck.test.crowdedkingdoms.com";
|
|
21
21
|
/** The bare hostname, for callers that need to compare rather than dial. */
|
|
22
|
-
export declare const CROWDY_DEFAULT_HOST = "ck.
|
|
22
|
+
export declare const CROWDY_DEFAULT_HOST = "ck.test.crowdedkingdoms.com";
|
|
23
23
|
//# sourceMappingURL=default-origin.d.ts.map
|
package/dist/default-origin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* GENERATED — do not edit. The operator tooling's
|
|
3
|
-
* `sync-client-origins.mjs --write --tier
|
|
3
|
+
* `sync-client-origins.mjs --write --tier test` writes this file, and
|
|
4
4
|
* `check-sdk-default-origin.mjs` refuses it when it names the wrong tier or a
|
|
5
5
|
* host that declaration does not carry. Regenerate; never hand-edit.
|
|
6
6
|
*
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
* than no default at all. Every fallback this SDK ever removed named a host that
|
|
11
11
|
* was already dead. A generated file plus a gate is what makes this one different.
|
|
12
12
|
*
|
|
13
|
-
* Source: the operator's per-tier public CK API origin declaration, tier '
|
|
13
|
+
* Source: the operator's per-tier public CK API origin declaration, tier 'test'
|
|
14
14
|
*/
|
|
15
15
|
/** The tier this build of the SDK is published for. */
|
|
16
|
-
export const CROWDY_DEFAULT_TIER = '
|
|
16
|
+
export const CROWDY_DEFAULT_TIER = 'test';
|
|
17
17
|
/** The public CK API origin for that tier. */
|
|
18
|
-
export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.
|
|
18
|
+
export const CROWDY_DEFAULT_HTTP_ORIGIN = 'https://ck.test.crowdedkingdoms.com';
|
|
19
19
|
/** The same host over WebSocket. A scheme is composed; a hostname is looked up. */
|
|
20
|
-
export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.
|
|
20
|
+
export const CROWDY_DEFAULT_WS_ORIGIN = 'wss://ck.test.crowdedkingdoms.com';
|
|
21
21
|
/** The bare hostname, for callers that need to compare rather than dial. */
|
|
22
|
-
export const CROWDY_DEFAULT_HOST = 'ck.
|
|
22
|
+
export const CROWDY_DEFAULT_HOST = 'ck.test.crowdedkingdoms.com';
|
package/dist/domains/udp.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { GraphQLClient } from '../client.js';
|
|
2
2
|
import type { SubscriptionManager, UdpNotificationHandlers } from '../subscriptions.js';
|
|
3
|
-
import { type ConnectUdpProxyMutation, type UdpProxyConnectionStatusQuery, type SendActorUpdateMutationVariables, type SendVoxelUpdateMutationVariables, type SendAudioPacketMutationVariables, type SendTextPacketMutationVariables, type SendClientEventMutationVariables, type SendSingleActorMessageMutationVariables, type SendChannelMessageMutationVariables } from '../generated/graphql.js';
|
|
3
|
+
import { type ConnectUdpProxyMutation, type UdpProxyConnectionStatusQuery, type SendActorUpdateMutationVariables, type SendVoxelUpdateMutationVariables, type SendAudioPacketMutationVariables, type SendVideoPacketMutationVariables, type SendTextPacketMutationVariables, type SendClientEventMutationVariables, type SendSingleActorMessageMutationVariables, type SendChannelMessageMutationVariables } from '../generated/graphql.js';
|
|
4
4
|
import type { RealtimeMetrics } from '../metrics.js';
|
|
5
5
|
import type { SpatialNotification } from '../realtime.js';
|
|
6
|
+
import { type VideoCodec } from '../media/video-frames.js';
|
|
6
7
|
/**
|
|
7
8
|
* UDP proxy access for browser-style clients that can't open raw UDP sockets.
|
|
8
9
|
* Exposed as `client.udp`; for game loops prefer the ergonomic, app-scoped
|
|
@@ -250,6 +251,51 @@ export declare class UdpAPI {
|
|
|
250
251
|
sendAudioPacketAndWait(input: SendAudioPacketMutationVariables['input'], options?: {
|
|
251
252
|
timeoutMs?: number;
|
|
252
253
|
}): Promise<SpatialNotification>;
|
|
254
|
+
/**
|
|
255
|
+
* Send ONE webcam video fragment, fanned out to nearby actors as a
|
|
256
|
+
* `ClientVideoNotification` (Buddy v0.25.0). Fire-and-forget; opens a UDP
|
|
257
|
+
* proxy session automatically. Gated by the `use_video_chat` runtime
|
|
258
|
+
* permission at app AND grid level — without it the game server replies
|
|
259
|
+
* asynchronously with a `GenericErrorResponse` (`errorCode` `UNAUTHORIZED`).
|
|
260
|
+
* Prefer {@link sendVideoFrame}, which fragments a whole encoded frame; this is
|
|
261
|
+
* the single-datagram primitive beneath it.
|
|
262
|
+
*
|
|
263
|
+
* On the GraphQL proxy path this is a mutation PER FRAGMENT (30–80 a second for
|
|
264
|
+
* live video). Enable `binaryTransport` so video rides the relay.
|
|
265
|
+
*
|
|
266
|
+
* @param input - {@link ClientVideoPacketInput}: `videoData` is base64 of a
|
|
267
|
+
* 6-byte fragment header plus a slice of the encoded frame (see
|
|
268
|
+
* `fragmentFrame`); `distance` defaults to 1, `decayRate` to 0.
|
|
269
|
+
* @returns `true` when accepted for sending — **not** confirmation of delivery.
|
|
270
|
+
*/
|
|
271
|
+
sendVideoPacket(input: SendVideoPacketMutationVariables['input']): Promise<boolean>;
|
|
272
|
+
/**
|
|
273
|
+
* Send one encoded webcam frame (a JPEG or WebP file) as however many
|
|
274
|
+
* fragments it needs (at most 16, ~17.8 KB), each a {@link sendVideoPacket}.
|
|
275
|
+
* Receivers reassemble with `VideoFrameAssembler`. Every receiver in range
|
|
276
|
+
* pays the egress bytes: keep `distance` at 0–1, frames small (≤ 8 KB) and
|
|
277
|
+
* the rate low (≤ 10 fps).
|
|
278
|
+
*
|
|
279
|
+
* @param input - `appId`, `chunk`, `uuid`, optional `distance` / `decayRate`,
|
|
280
|
+
* plus `frame` (encoded bytes), `frameId` (0–65535, +1 per frame, wraps —
|
|
281
|
+
* the caller keeps the counter) and `codec` (0 JPEG default, 1 WebP).
|
|
282
|
+
* @returns the number of fragments sent.
|
|
283
|
+
* @throws {RangeError} when the frame exceeds 16 fragments; nothing is sent.
|
|
284
|
+
*/
|
|
285
|
+
sendVideoFrame(input: {
|
|
286
|
+
appId: string;
|
|
287
|
+
chunk: {
|
|
288
|
+
x: string;
|
|
289
|
+
y: string;
|
|
290
|
+
z: string;
|
|
291
|
+
};
|
|
292
|
+
uuid: string;
|
|
293
|
+
frame: Uint8Array;
|
|
294
|
+
frameId: number;
|
|
295
|
+
codec?: VideoCodec;
|
|
296
|
+
distance?: number;
|
|
297
|
+
decayRate?: number;
|
|
298
|
+
}): Promise<number>;
|
|
253
299
|
/**
|
|
254
300
|
* Send a spatial text/chat packet, fanned out to nearby actors as a
|
|
255
301
|
* `ClientTextNotification`. Fire-and-forget; opens a UDP proxy session
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"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"}
|
package/dist/domains/udp.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ConnectUdpProxyDocument, DisconnectUdpProxyDocument, UdpProxyConnectionStatusDocument, SendActorUpdateDocument, SendVoxelUpdateDocument, SendAudioPacketDocument, SendTextPacketDocument, SendClientEventDocument, SendSingleActorMessageDocument, SendChannelMessageDocument, } from '../generated/graphql.js';
|
|
1
|
+
import { ConnectUdpProxyDocument, DisconnectUdpProxyDocument, UdpProxyConnectionStatusDocument, SendActorUpdateDocument, SendVoxelUpdateDocument, SendAudioPacketDocument, SendVideoPacketDocument, SendTextPacketDocument, SendClientEventDocument, SendSingleActorMessageDocument, SendChannelMessageDocument, } from '../generated/graphql.js';
|
|
2
2
|
import { payloadBytesOf } from '../metrics.js';
|
|
3
3
|
import { SequenceAllocator } from '../utils.js';
|
|
4
|
-
import { serializeActorUpdate, serializeAudioPacket, serializeChannelMessage, serializeClientEvent, serializeSingleActorMessage, serializeTextPacket, serializeVoxelUpdate, } from '../binary-wire.js';
|
|
4
|
+
import { serializeActorUpdate, serializeAudioPacket, serializeChannelMessage, serializeClientEvent, serializeSingleActorMessage, serializeTextPacket, serializeVideoPacket, serializeVoxelUpdate, } from '../binary-wire.js';
|
|
5
|
+
import { fragmentFrame } from '../media/video-frames.js';
|
|
6
|
+
import { encodeBase64 } from '../utils.js';
|
|
5
7
|
/**
|
|
6
8
|
* UDP proxy access for browser-style clients that can't open raw UDP sockets.
|
|
7
9
|
* Exposed as `client.udp`; for game loops prefer the ergonomic, app-scoped
|
|
@@ -358,6 +360,61 @@ export class UdpAPI {
|
|
|
358
360
|
await this.sendAudioPacket(request);
|
|
359
361
|
return wait;
|
|
360
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* Send ONE webcam video fragment, fanned out to nearby actors as a
|
|
365
|
+
* `ClientVideoNotification` (Buddy v0.25.0). Fire-and-forget; opens a UDP
|
|
366
|
+
* proxy session automatically. Gated by the `use_video_chat` runtime
|
|
367
|
+
* permission at app AND grid level — without it the game server replies
|
|
368
|
+
* asynchronously with a `GenericErrorResponse` (`errorCode` `UNAUTHORIZED`).
|
|
369
|
+
* Prefer {@link sendVideoFrame}, which fragments a whole encoded frame; this is
|
|
370
|
+
* the single-datagram primitive beneath it.
|
|
371
|
+
*
|
|
372
|
+
* On the GraphQL proxy path this is a mutation PER FRAGMENT (30–80 a second for
|
|
373
|
+
* live video). Enable `binaryTransport` so video rides the relay.
|
|
374
|
+
*
|
|
375
|
+
* @param input - {@link ClientVideoPacketInput}: `videoData` is base64 of a
|
|
376
|
+
* 6-byte fragment header plus a slice of the encoded frame (see
|
|
377
|
+
* `fragmentFrame`); `distance` defaults to 1, `decayRate` to 0.
|
|
378
|
+
* @returns `true` when accepted for sending — **not** confirmation of delivery.
|
|
379
|
+
*/
|
|
380
|
+
async sendVideoPacket(input) {
|
|
381
|
+
const viaRelay = await this.sendViaRelay((ctx) => serializeVideoPacket(ctx, input));
|
|
382
|
+
if (viaRelay !== null) {
|
|
383
|
+
this.record('video', input);
|
|
384
|
+
return viaRelay;
|
|
385
|
+
}
|
|
386
|
+
const data = await this.gql.request(SendVideoPacketDocument, { input });
|
|
387
|
+
this.record('video', input);
|
|
388
|
+
return data.sendVideoPacket;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Send one encoded webcam frame (a JPEG or WebP file) as however many
|
|
392
|
+
* fragments it needs (at most 16, ~17.8 KB), each a {@link sendVideoPacket}.
|
|
393
|
+
* Receivers reassemble with `VideoFrameAssembler`. Every receiver in range
|
|
394
|
+
* pays the egress bytes: keep `distance` at 0–1, frames small (≤ 8 KB) and
|
|
395
|
+
* the rate low (≤ 10 fps).
|
|
396
|
+
*
|
|
397
|
+
* @param input - `appId`, `chunk`, `uuid`, optional `distance` / `decayRate`,
|
|
398
|
+
* plus `frame` (encoded bytes), `frameId` (0–65535, +1 per frame, wraps —
|
|
399
|
+
* the caller keeps the counter) and `codec` (0 JPEG default, 1 WebP).
|
|
400
|
+
* @returns the number of fragments sent.
|
|
401
|
+
* @throws {RangeError} when the frame exceeds 16 fragments; nothing is sent.
|
|
402
|
+
*/
|
|
403
|
+
async sendVideoFrame(input) {
|
|
404
|
+
const fragments = fragmentFrame(input.frame, input.frameId, input.codec);
|
|
405
|
+
for (const fragment of fragments) {
|
|
406
|
+
await this.sendVideoPacket({
|
|
407
|
+
appId: input.appId,
|
|
408
|
+
chunk: input.chunk,
|
|
409
|
+
uuid: input.uuid,
|
|
410
|
+
videoData: encodeBase64(fragment),
|
|
411
|
+
distance: input.distance,
|
|
412
|
+
decayRate: input.decayRate,
|
|
413
|
+
sequenceNumber: input.frameId & 0xff,
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
return fragments.length;
|
|
417
|
+
}
|
|
361
418
|
/**
|
|
362
419
|
* Send a spatial text/chat packet, fanned out to nearby actors as a
|
|
363
420
|
* `ClientTextNotification`. Fire-and-forget; opens a UDP proxy session
|