@crowdedkingdoms/crowdyjs 18.4.1 → 18.5.0-dev.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/MIGRATION.md +25 -0
- package/README.md +22 -15
- package/dist/binary-wire.d.ts +22 -0
- package/dist/binary-wire.d.ts.map +1 -1
- package/dist/binary-wire.js +59 -0
- package/dist/default-origin.d.ts +6 -6
- package/dist/default-origin.d.ts.map +1 -1
- package/dist/default-origin.js +6 -6
- package/dist/domains/udp.d.ts +29 -1
- package/dist/domains/udp.d.ts.map +1 -1
- package/dist/domains/udp.js +40 -2
- package/dist/generated/graphql-schema.d.ts +22 -0
- package/dist/generated/graphql-schema.d.ts.map +1 -1
- package/dist/generated/graphql.d.ts +7 -0
- package/dist/generated/graphql.d.ts.map +1 -1
- package/dist/generated/graphql.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/MIGRATION.md
CHANGED
|
@@ -120,6 +120,31 @@ super-admin's session). There is no SDK replacement.
|
|
|
120
120
|
`dev`'s SDL after #417 merged (`npm run schema:sync:paths -- --schema <that schema.gql>`, then
|
|
121
121
|
`npm run codegen`).
|
|
122
122
|
|
|
123
|
+
## 18.5.0: channel messages limited by distance
|
|
124
|
+
|
|
125
|
+
Additive. `client.udp.sendRangedChannelMessage(input)` publishes to a channel like
|
|
126
|
+
`sendChannelMessage`, but only members near an origin chunk receive it: a member gets it when one of
|
|
127
|
+
its live actors is in `input.appId` within `input.maxDistance` chunks of `input.chunk`, measured as
|
|
128
|
+
the straight-line distance between chunk coordinates, boundary included. `maxDistance` is an integer
|
|
129
|
+
from 0 (the origin chunk only) to 2147483647; it is not the 0-8 Chebyshev ring count spatial sends
|
|
130
|
+
take. A member with no live actor does not receive it.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
await client.udp.sendRangedChannelMessage({
|
|
134
|
+
channelId,
|
|
135
|
+
uuid: self.uuid,
|
|
136
|
+
payload: encodeBase64(bytes),
|
|
137
|
+
appId,
|
|
138
|
+
chunk: { x: '10', y: '0', z: '-4' },
|
|
139
|
+
maxDistance: 6,
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Members receive the ordinary `channelMessage` notification, so receivers need no change and an older
|
|
144
|
+
SDK receives these messages too. The send right is the channel's `send_messages`, as for
|
|
145
|
+
`sendChannelMessage`; a refusal arrives as a `genericError` (`UNAUTHORIZED`, or `INVALID_APP_ID` when
|
|
146
|
+
`appId` is not the token's app). It needs ck-api with `sendRangedChannelMessage` and Buddy v0.35.0.
|
|
147
|
+
|
|
123
148
|
## 18.4.1: the generated types come from graphql-codegen 7
|
|
124
149
|
|
|
125
150
|
No call changes, and the GraphQL documents the SDK sends are byte-for-byte the same. Thirteen types
|
package/README.md
CHANGED
|
@@ -12,19 +12,23 @@ gameplay, minted per app through `client.portal`.
|
|
|
12
12
|
|
|
13
13
|
Start here:
|
|
14
14
|
|
|
15
|
-
- [SDK guide](https://docs.crowdedkingdoms.com/crowdyjs/readme) — the canonical
|
|
15
|
+
- [SDK guide](https://docs.dev.crowdedkingdoms.com/crowdyjs/readme) — the canonical
|
|
16
16
|
walkthrough of everything in this README.
|
|
17
|
-
- [Build a game](https://docs.crowdedkingdoms.com/build-a-game/intro) — a
|
|
17
|
+
- [Build a game](https://docs.dev.crowdedkingdoms.com/build-a-game/intro) — a
|
|
18
18
|
hands-on tutorial from sign-in to a playable voxel game.
|
|
19
|
-
- [Platform overview](https://docs.crowdedkingdoms.com/overview/client-workflow)
|
|
19
|
+
- [Platform overview](https://docs.dev.crowdedkingdoms.com/overview/client-workflow)
|
|
20
20
|
— how a client session flows through the platform.
|
|
21
21
|
|
|
22
22
|
## Install
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
|
-
npm install @crowdedkingdoms/crowdyjs
|
|
25
|
+
npm install @crowdedkingdoms/crowdyjs@dev
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
This README is the `dev` branch's: it documents the release on the `dev` dist-tag
|
|
29
|
+
(`npm view @crowdedkingdoms/crowdyjs dist-tags`), and its links go to the dev docs site. A
|
|
30
|
+
plain `npm install` resolves `latest`, the production release, which has no `client.exec`.
|
|
31
|
+
|
|
28
32
|
CrowdyJS targets browsers by default and uses native `fetch`, `WebSocket`,
|
|
29
33
|
`crypto`, `btoa`, and `atob`. Node tools can still use the SDK, but must
|
|
30
34
|
provide browser-compatible globals when opening realtime connections (e.g.
|
|
@@ -183,8 +187,8 @@ Notes:
|
|
|
183
187
|
- Use `client.auth.setToken(token)` to seed a token externally (e.g. when
|
|
184
188
|
restoring auth from a non-default storage).
|
|
185
189
|
|
|
186
|
-
Deeper reading: [Portals & app-scoped tokens](https://docs.crowdedkingdoms.com/management-api/portals-and-app-tokens)
|
|
187
|
-
and [Sign in](https://docs.crowdedkingdoms.com/management-api/authentication).
|
|
190
|
+
Deeper reading: [Portals & app-scoped tokens](https://docs.dev.crowdedkingdoms.com/management-api/portals-and-app-tokens)
|
|
191
|
+
and [Sign in](https://docs.dev.crowdedkingdoms.com/management-api/authentication).
|
|
188
192
|
|
|
189
193
|
### Token refresh during gameplay
|
|
190
194
|
|
|
@@ -245,7 +249,7 @@ never told about, so a native refresh without it is a re-placement.
|
|
|
245
249
|
| `client.marketplace` | Player-authorized grid claims (`claimGridOwnership`, `claimGridChunk`, `releaseClaimedGrid`, requests and invites) and studio moderation of player code (admission queue, listing administration, claim policy). Mods publish and install through `client.exec`. |
|
|
246
250
|
| `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. |
|
|
247
251
|
| `client.crowdyStudioGitHub` | Optional GitHub repository for a Crowdy Studio project: status, `bind` (push the project in, or take the repository), `unbind`, `refresh`, `layout`, `tree`, `getFile`, commit-guarded `putFile` / `deleteFile`. While bound the repository is the working tree and every Studio save commits; the project's `files` are the server's mirror at `github.sha`. Never required. |
|
|
248
|
-
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendVideoPacket` / `sendVideoFrame`, `sendTextPacket`, `sendClientEvent`, `sendSingleActorMessage`, `sendChannelMessage`). |
|
|
252
|
+
| `client.udp` | UDP proxy subscriptions + spatial mutations (`sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`, `sendVideoPacket` / `sendVideoFrame`, `sendTextPacket`, `sendClientEvent`, `sendSingleActorMessage`, `sendChannelMessage`, `sendRangedChannelMessage`). |
|
|
249
253
|
| `client.realtime` | Connection status, manual `connect()` / `disconnect()`, `onStatus()` listener. |
|
|
250
254
|
| `client.refreshGameplayToken()` | Safely rotates an active game client's app token (see [Token refresh](#token-refresh-during-gameplay)). |
|
|
251
255
|
| `client.world(appId)` | Higher-level helpers for browser games (`actor.join`, `actor.sendState`, `actor.sendText`, `actor.sendToActor`). |
|
|
@@ -307,7 +311,7 @@ query AppForRouting($appId: BigInt!) {
|
|
|
307
311
|
`CrowdyClient` with `httpUrl: gameApiUrl` (and the matching `wsUrl`) holding
|
|
308
312
|
that app's app-scoped token, then drive gameplay through that client. Apps
|
|
309
313
|
with no `gameApiUrl` keep working against the default `httpUrl` you
|
|
310
|
-
configured. See [Loading an app's Game API](https://docs.crowdedkingdoms.com/crowdyjs/shared-environment-routing).
|
|
314
|
+
configured. See [Loading an app's Game API](https://docs.dev.crowdedkingdoms.com/crowdyjs/shared-environment-routing).
|
|
311
315
|
|
|
312
316
|
## Realtime notifications
|
|
313
317
|
|
|
@@ -440,7 +444,10 @@ The plain `sendActorUpdate`, `sendVoxelUpdate`, `sendAudioPacket`,
|
|
|
440
444
|
result immediately. The `AndWait` variants allocate a `sequenceNumber` when
|
|
441
445
|
one is missing and wait for either a matching notification or
|
|
442
446
|
`GenericErrorResponse`. `sendChannelMessage` broadcasts an opaque payload on a
|
|
443
|
-
channel.
|
|
447
|
+
channel. `sendRangedChannelMessage` publishes on a channel too, but only members
|
|
448
|
+
with a live actor within `maxDistance` chunks (straight-line distance between
|
|
449
|
+
chunk coordinates) of `chunk` receive it; they get the same `channelMessage`
|
|
450
|
+
notification.
|
|
444
451
|
|
|
445
452
|
### Bundled sends on the binary relay
|
|
446
453
|
|
|
@@ -618,7 +625,7 @@ reach your bundle. Reads are synchronous snapshots and writes happen on
|
|
|
618
625
|
WebSocket events (not `requestAnimationFrame`), so render loops read freely
|
|
619
626
|
and a backgrounded tab keeps ingesting updates; pass `workerTicker()` to also
|
|
620
627
|
keep timer-driven sends at full rate while hidden. See the
|
|
621
|
-
[World Stores guide](https://docs.crowdedkingdoms.com/crowdyjs/stores).
|
|
628
|
+
[World Stores guide](https://docs.dev.crowdedkingdoms.com/crowdyjs/stores).
|
|
622
629
|
|
|
623
630
|
## Game Kit
|
|
624
631
|
|
|
@@ -701,7 +708,7 @@ exec.onReconnect((host) => console.log('moved to', host));
|
|
|
701
708
|
|
|
702
709
|
Integers above 2^53 decode as `number` and lose precision unless you pass
|
|
703
710
|
`{ decode: { useBigInt64: true } }`. The wire format is in the
|
|
704
|
-
[ck-exec docs](https://docs.crowdedkingdoms.com/exec/intro).
|
|
711
|
+
[ck-exec docs](https://docs.dev.crowdedkingdoms.com/exec/intro).
|
|
705
712
|
|
|
706
713
|
### A mod's CLIENT half
|
|
707
714
|
|
|
@@ -772,7 +779,7 @@ counts what was dropped); `invoke` sends at most 256 KiB each way and is refused
|
|
|
772
779
|
module is not running. `NOT_FOUND` holds a CLIENT half back 15 s and `RATE_LIMITED` 60 s. The
|
|
773
780
|
grid's owner is asked about their own CLIENT halves like anyone; answer yes in `confirm` when
|
|
774
781
|
`prompt.authorId` is the player. See
|
|
775
|
-
[CLIENT halves](https://docs.crowdedkingdoms.com/exec/client-halves).
|
|
782
|
+
[CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves).
|
|
776
783
|
|
|
777
784
|
## Hosting a game on Crowdy Games
|
|
778
785
|
|
|
@@ -891,8 +898,8 @@ CLIENT project needs ck-api `v2.25.1` or later. A CLIENT crate still on the lega
|
|
|
891
898
|
`mountCrowdyStudio` and the controller take `mods: client.exec`. Crowdy Studio runs nothing
|
|
892
899
|
on legacy player compute since 18.0.0.
|
|
893
900
|
|
|
894
|
-
See [CLIENT halves](https://docs.crowdedkingdoms.com/exec/client-halves), [mods](https://docs.crowdedkingdoms.com/exec/mods)
|
|
895
|
-
and [Embed Crowdy Studio in your game](https://docs.crowdedkingdoms.com/crowdyjs/crowdy-studio-embed).
|
|
901
|
+
See [CLIENT halves](https://docs.dev.crowdedkingdoms.com/exec/client-halves), [mods](https://docs.dev.crowdedkingdoms.com/exec/mods)
|
|
902
|
+
and [Embed Crowdy Studio in your game](https://docs.dev.crowdedkingdoms.com/crowdyjs/crowdy-studio-embed).
|
|
896
903
|
|
|
897
904
|
### The Studio agent (DeepSeek Harness in the browser)
|
|
898
905
|
|
|
@@ -1071,7 +1078,7 @@ no other repositories and no network access required:
|
|
|
1071
1078
|
`src/generated/graphql-schema.ts`, the generated schema types.
|
|
1072
1079
|
|
|
1073
1080
|
Schema refresh is explicit, from the published
|
|
1074
|
-
[SDL](https://docs.crowdedkingdoms.com/schema/game-api.graphql):
|
|
1081
|
+
[SDL](https://docs.dev.crowdedkingdoms.com/schema/game-api.graphql):
|
|
1075
1082
|
|
|
1076
1083
|
```bash
|
|
1077
1084
|
npm run schema:sync:prod
|
package/dist/binary-wire.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare const WireMessageType: {
|
|
|
51
51
|
readonly GENERIC_ERROR_MESSAGE: 3;
|
|
52
52
|
readonly CHANNEL_MESSAGE_REQUEST: 17;
|
|
53
53
|
readonly CHANNEL_MESSAGE_NOTIFICATION: 18;
|
|
54
|
+
readonly CHANNEL_MESSAGE_RANGED_REQUEST: 32;
|
|
54
55
|
readonly ACTOR_UPDATE_REQUEST_2: 128;
|
|
55
56
|
readonly ACTOR_UPDATE_RESPONSE_2: 129;
|
|
56
57
|
readonly ACTOR_UPDATE_NOTIFICATION_2: 130;
|
|
@@ -158,6 +159,27 @@ export declare function serializeChannelMessage(ctx: RelaySignContext, input: {
|
|
|
158
159
|
payload?: string | null;
|
|
159
160
|
sequenceNumber?: number | null;
|
|
160
161
|
}): Promise<Uint8Array>;
|
|
162
|
+
/** Largest `maxDistance` a ranged channel message may carry (the GraphQL `Int` ceiling). */
|
|
163
|
+
export declare const CHANNEL_RANGED_MAX_DISTANCE = 2147483647;
|
|
164
|
+
/**
|
|
165
|
+
* CHANNEL_MESSAGE_RANGED_REQUEST (Buddy v0.35.0):
|
|
166
|
+
* `[1B type=32][8B channelId][32B uuid][8B appId][8B chunkX][8B chunkY][8B chunkZ]
|
|
167
|
+
* [4B maxDistance u32][2B payloadLen][payload][1B containsAuth][32B HMAC]
|
|
168
|
+
* [8B gameTokenId][1B seq]` — HMAC over everything before it, as for 17.
|
|
169
|
+
*/
|
|
170
|
+
export declare function serializeRangedChannelMessage(ctx: RelaySignContext, input: {
|
|
171
|
+
channelId: string;
|
|
172
|
+
uuid: string;
|
|
173
|
+
payload?: string | null;
|
|
174
|
+
appId: string;
|
|
175
|
+
chunk: {
|
|
176
|
+
x: string;
|
|
177
|
+
y: string;
|
|
178
|
+
z: string;
|
|
179
|
+
};
|
|
180
|
+
maxDistance: number;
|
|
181
|
+
sequenceNumber?: number | null;
|
|
182
|
+
}): Promise<Uint8Array>;
|
|
161
183
|
/**
|
|
162
184
|
* Parse one relay BINARY frame (one Buddy datagram, possibly a
|
|
163
185
|
* MESSAGE_BUNDLE) into notification objects. Unparseable inner messages are
|
|
@@ -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;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AACrC,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAC5C,uEAAuE;AACvE,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,qEAAqE;AACrE,eAAO,MAAM,6BAA6B,QACmC,CAAC;AAE9E;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,MAAM,CAInE;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,CAwB5E;AAED,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
|
@@ -86,6 +86,9 @@ export const WireMessageType = {
|
|
|
86
86
|
GENERIC_ERROR_MESSAGE: 3,
|
|
87
87
|
CHANNEL_MESSAGE_REQUEST: 17,
|
|
88
88
|
CHANNEL_MESSAGE_NOTIFICATION: 18,
|
|
89
|
+
// Buddy v0.35.0: a channel publish only members near an origin chunk receive
|
|
90
|
+
// (they get an ordinary CHANNEL_MESSAGE_NOTIFICATION).
|
|
91
|
+
CHANNEL_MESSAGE_RANGED_REQUEST: 32,
|
|
89
92
|
ACTOR_UPDATE_REQUEST_2: 128,
|
|
90
93
|
ACTOR_UPDATE_RESPONSE_2: 129,
|
|
91
94
|
ACTOR_UPDATE_NOTIFICATION_2: 130,
|
|
@@ -322,6 +325,62 @@ export async function serializeChannelMessage(ctx, input) {
|
|
|
322
325
|
tail.setUint8(prefixLen + HMAC_SIZE + 8, (input.sequenceNumber ?? 0) & 0xff);
|
|
323
326
|
return out;
|
|
324
327
|
}
|
|
328
|
+
/** Largest `maxDistance` a ranged channel message may carry (the GraphQL `Int` ceiling). */
|
|
329
|
+
export const CHANNEL_RANGED_MAX_DISTANCE = 0x7fffffff;
|
|
330
|
+
/**
|
|
331
|
+
* CHANNEL_MESSAGE_RANGED_REQUEST (Buddy v0.35.0):
|
|
332
|
+
* `[1B type=32][8B channelId][32B uuid][8B appId][8B chunkX][8B chunkY][8B chunkZ]
|
|
333
|
+
* [4B maxDistance u32][2B payloadLen][payload][1B containsAuth][32B HMAC]
|
|
334
|
+
* [8B gameTokenId][1B seq]` — HMAC over everything before it, as for 17.
|
|
335
|
+
*/
|
|
336
|
+
export async function serializeRangedChannelMessage(ctx, input) {
|
|
337
|
+
const payload = input.payload ? decodeBase64(input.payload) : new Uint8Array(0);
|
|
338
|
+
if (payload.length > 1024) {
|
|
339
|
+
throw new Error(`Channel payload exceeds 1024 bytes: ${payload.length}`);
|
|
340
|
+
}
|
|
341
|
+
if (!Number.isInteger(input.maxDistance) ||
|
|
342
|
+
input.maxDistance < 0 ||
|
|
343
|
+
input.maxDistance > CHANNEL_RANGED_MAX_DISTANCE) {
|
|
344
|
+
throw new Error(`maxDistance must be an integer from 0 to ${CHANNEL_RANGED_MAX_DISTANCE}: ${input.maxDistance}`);
|
|
345
|
+
}
|
|
346
|
+
const uuidBytes = textEncoder.encode(input.uuid);
|
|
347
|
+
if (uuidBytes.length !== UUID_SIZE) {
|
|
348
|
+
throw new Error(`Invalid uuid length: must be exactly ${UUID_SIZE} bytes when UTF-8 encoded. Received ${uuidBytes.length} bytes.`);
|
|
349
|
+
}
|
|
350
|
+
const prefixLen = 1 + 8 + UUID_SIZE + 32 + 4 + 2 + payload.length + 1;
|
|
351
|
+
const prefix = new Uint8Array(prefixLen);
|
|
352
|
+
const view = new DataView(prefix.buffer);
|
|
353
|
+
let off = 0;
|
|
354
|
+
view.setUint8(off, WireMessageType.CHANNEL_MESSAGE_RANGED_REQUEST);
|
|
355
|
+
off += 1;
|
|
356
|
+
view.setBigUint64(off, BigInt(input.channelId), true);
|
|
357
|
+
off += 8;
|
|
358
|
+
prefix.set(uuidBytes, off);
|
|
359
|
+
off += UUID_SIZE;
|
|
360
|
+
view.setBigInt64(off, BigInt(input.appId), true);
|
|
361
|
+
off += 8;
|
|
362
|
+
view.setBigInt64(off, BigInt(input.chunk.x), true);
|
|
363
|
+
off += 8;
|
|
364
|
+
view.setBigInt64(off, BigInt(input.chunk.y), true);
|
|
365
|
+
off += 8;
|
|
366
|
+
view.setBigInt64(off, BigInt(input.chunk.z), true);
|
|
367
|
+
off += 8;
|
|
368
|
+
view.setUint32(off, input.maxDistance, true);
|
|
369
|
+
off += 4;
|
|
370
|
+
view.setUint16(off, payload.length, true);
|
|
371
|
+
off += 2;
|
|
372
|
+
prefix.set(payload, off);
|
|
373
|
+
off += payload.length;
|
|
374
|
+
view.setUint8(off, 1); // containsAuth
|
|
375
|
+
const hmac = await signWithToken(ctx, prefix);
|
|
376
|
+
const out = new Uint8Array(prefixLen + HMAC_SIZE + 8 + 1);
|
|
377
|
+
out.set(prefix, 0);
|
|
378
|
+
out.set(hmac, prefixLen);
|
|
379
|
+
const tail = new DataView(out.buffer);
|
|
380
|
+
tail.setBigUint64(prefixLen + HMAC_SIZE, ctx.gameTokenId, true);
|
|
381
|
+
tail.setUint8(prefixLen + HMAC_SIZE + 8, (input.sequenceNumber ?? 0) & 0xff);
|
|
382
|
+
return out;
|
|
383
|
+
}
|
|
325
384
|
function stripNulls(value) {
|
|
326
385
|
return value.replace(/\0/g, '');
|
|
327
386
|
}
|
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 dev` 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 'dev'
|
|
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 = "dev";
|
|
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.dev.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.dev.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.dev.crowdedkingdoms.com";
|
|
23
23
|
//# sourceMappingURL=default-origin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"default-origin.d.ts","sourceRoot":"","sources":["../src/default-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"default-origin.d.ts","sourceRoot":"","sources":["../src/default-origin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,uDAAuD;AACvD,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,8CAA8C;AAC9C,eAAO,MAAM,0BAA0B,uCAAuC,CAAC;AAE/E,mFAAmF;AACnF,eAAO,MAAM,wBAAwB,qCAAqC,CAAC;AAE3E,4EAA4E;AAC5E,eAAO,MAAM,mBAAmB,+BAA+B,CAAC"}
|
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 dev` 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 'dev'
|
|
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 = 'dev';
|
|
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.dev.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.dev.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.dev.crowdedkingdoms.com';
|
package/dist/domains/udp.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
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 SendVideoPacketMutationVariables, 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, type SendRangedChannelMessageMutationVariables } from '../generated/graphql.js';
|
|
4
4
|
import type { RealtimeMetrics } from '../metrics.js';
|
|
5
5
|
import type { SpatialNotification } from '../realtime.js';
|
|
6
6
|
import { type VideoCodec } from '../media/video-frames.js';
|
|
@@ -466,6 +466,34 @@ export declare class UdpAPI {
|
|
|
466
466
|
* @throws {CrowdyGraphQLError} on auth/validation failures.
|
|
467
467
|
*/
|
|
468
468
|
sendChannelMessage(input: SendChannelMessageMutationVariables['input']): Promise<boolean>;
|
|
469
|
+
/**
|
|
470
|
+
* Publish a message to a channel that only members near an origin chunk
|
|
471
|
+
* receive (needs ck-api with `sendRangedChannelMessage` and Buddy v0.35.0).
|
|
472
|
+
* A member receives it, through the same `channelMessage` handler as
|
|
473
|
+
* {@link sendChannelMessage}, when one of its live actors is in `appId`
|
|
474
|
+
* within `maxDistance` chunks of `chunk`, measured as the straight-line
|
|
475
|
+
* distance between chunk coordinates, boundary included. A member with no
|
|
476
|
+
* live actor does not receive it. Same send right as `sendChannelMessage`;
|
|
477
|
+
* the sender receives no echo.
|
|
478
|
+
*
|
|
479
|
+
* @param input - {@link RangedChannelMessageInput}:
|
|
480
|
+
* - `channelId` — the channel id (`groups.group_id`) as a `BigInt` decimal
|
|
481
|
+
* string.
|
|
482
|
+
* - `uuid` — the sender's own actor id: exactly 32 ASCII characters.
|
|
483
|
+
* - `payload` — message body, base64-encoded; opaque to the server, max
|
|
484
|
+
* 1024 bytes.
|
|
485
|
+
* - `appId` — the origin's app; must be this token's app.
|
|
486
|
+
* - `chunk` — the origin chunk `{ x, y, z }` (`BigInt` decimal strings),
|
|
487
|
+
* usually the sender's own chunk.
|
|
488
|
+
* - `maxDistance` — integer chunks, 0 (the origin chunk only) to
|
|
489
|
+
* 2147483647. Not the 0-8 Chebyshev ring count spatial sends take.
|
|
490
|
+
* - `sequenceNumber` — optional uint8 (0-255) correlation id.
|
|
491
|
+
* @returns `true` when accepted for sending — **not** confirmation of
|
|
492
|
+
* delivery. A refusal (no send right: `UNAUTHORIZED`; another app:
|
|
493
|
+
* `INVALID_APP_ID`) arrives as a `genericError` notification.
|
|
494
|
+
* @throws {CrowdyGraphQLError} on auth/validation failures.
|
|
495
|
+
*/
|
|
496
|
+
sendRangedChannelMessage(input: SendRangedChannelMessageMutationVariables['input']): Promise<boolean>;
|
|
469
497
|
/**
|
|
470
498
|
* Subscribe to udpNotifications for a single app. Pass any combination of
|
|
471
499
|
* typename handlers; the returned function detaches all of them. The first
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"udp.d.ts","sourceRoot":"","sources":["../../src/domains/udp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EACV,mBAAmB,EACnB,uBAAuB,EACxB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAEL,KAAK,uBAAuB,EAG5B,KAAK,6BAA6B,EAElC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,gCAAgC,EAErC,KAAK,+BAA+B,EAEpC,KAAK,gCAAgC,EAErC,KAAK,uCAAuC,EAE5C,KAAK,mCAAmC,
|
|
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,7 @@
|
|
|
1
|
-
import { ConnectUdpProxyDocument, DisconnectUdpProxyDocument, UdpProxyConnectionStatusDocument, SendActorUpdateDocument, SendVoxelUpdateDocument, SendAudioPacketDocument, SendVideoPacketDocument, SendTextPacketDocument, SendClientEventDocument, SendSingleActorMessageDocument, SendChannelMessageDocument, } from '../generated/graphql.js';
|
|
1
|
+
import { ConnectUdpProxyDocument, DisconnectUdpProxyDocument, UdpProxyConnectionStatusDocument, SendActorUpdateDocument, SendVoxelUpdateDocument, SendAudioPacketDocument, SendVideoPacketDocument, SendTextPacketDocument, SendClientEventDocument, SendSingleActorMessageDocument, SendChannelMessageDocument, SendRangedChannelMessageDocument, } 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, serializeVideoPacket, serializeVoxelUpdate, } from '../binary-wire.js';
|
|
4
|
+
import { serializeActorUpdate, serializeAudioPacket, serializeChannelMessage, serializeClientEvent, serializeRangedChannelMessage, serializeSingleActorMessage, serializeTextPacket, serializeVideoPacket, serializeVoxelUpdate, } from '../binary-wire.js';
|
|
5
5
|
import { fragmentFrame } from '../media/video-frames.js';
|
|
6
6
|
import { encodeBase64 } from '../utils.js';
|
|
7
7
|
/**
|
|
@@ -669,6 +669,44 @@ export class UdpAPI {
|
|
|
669
669
|
this.record('channelMessage', input);
|
|
670
670
|
return data.sendChannelMessage;
|
|
671
671
|
}
|
|
672
|
+
/**
|
|
673
|
+
* Publish a message to a channel that only members near an origin chunk
|
|
674
|
+
* receive (needs ck-api with `sendRangedChannelMessage` and Buddy v0.35.0).
|
|
675
|
+
* A member receives it, through the same `channelMessage` handler as
|
|
676
|
+
* {@link sendChannelMessage}, when one of its live actors is in `appId`
|
|
677
|
+
* within `maxDistance` chunks of `chunk`, measured as the straight-line
|
|
678
|
+
* distance between chunk coordinates, boundary included. A member with no
|
|
679
|
+
* live actor does not receive it. Same send right as `sendChannelMessage`;
|
|
680
|
+
* the sender receives no echo.
|
|
681
|
+
*
|
|
682
|
+
* @param input - {@link RangedChannelMessageInput}:
|
|
683
|
+
* - `channelId` — the channel id (`groups.group_id`) as a `BigInt` decimal
|
|
684
|
+
* string.
|
|
685
|
+
* - `uuid` — the sender's own actor id: exactly 32 ASCII characters.
|
|
686
|
+
* - `payload` — message body, base64-encoded; opaque to the server, max
|
|
687
|
+
* 1024 bytes.
|
|
688
|
+
* - `appId` — the origin's app; must be this token's app.
|
|
689
|
+
* - `chunk` — the origin chunk `{ x, y, z }` (`BigInt` decimal strings),
|
|
690
|
+
* usually the sender's own chunk.
|
|
691
|
+
* - `maxDistance` — integer chunks, 0 (the origin chunk only) to
|
|
692
|
+
* 2147483647. Not the 0-8 Chebyshev ring count spatial sends take.
|
|
693
|
+
* - `sequenceNumber` — optional uint8 (0-255) correlation id.
|
|
694
|
+
* @returns `true` when accepted for sending — **not** confirmation of
|
|
695
|
+
* delivery. A refusal (no send right: `UNAUTHORIZED`; another app:
|
|
696
|
+
* `INVALID_APP_ID`) arrives as a `genericError` notification.
|
|
697
|
+
* @throws {CrowdyGraphQLError} on auth/validation failures.
|
|
698
|
+
*/
|
|
699
|
+
async sendRangedChannelMessage(input) {
|
|
700
|
+
await this.awaitGameplayTokenReady();
|
|
701
|
+
const viaRelay = await this.sendViaRelay((ctx) => serializeRangedChannelMessage(ctx, input));
|
|
702
|
+
if (viaRelay !== null) {
|
|
703
|
+
this.record('rangedChannelMessage', input);
|
|
704
|
+
return viaRelay;
|
|
705
|
+
}
|
|
706
|
+
const data = await this.gql.request(SendRangedChannelMessageDocument, { input });
|
|
707
|
+
this.record('rangedChannelMessage', input);
|
|
708
|
+
return data.sendRangedChannelMessage;
|
|
709
|
+
}
|
|
672
710
|
/**
|
|
673
711
|
* Subscribe to udpNotifications for a single app. Pass any combination of
|
|
674
712
|
* typename handlers; the returned function detaches all of them. The first
|
|
@@ -4587,6 +4587,8 @@ export type Mutation = {
|
|
|
4587
4587
|
sendChannelMessage: Scalars['Boolean']['output'];
|
|
4588
4588
|
/** Send a custom, app-defined client event (identified by eventType, a uint16) for spatial replication to nearby chunks; nearby actors receive it as a ClientEventNotification. Requires a bearer game token; opens a UDP proxy session automatically if none exists. Returns Boolean! that is true only when the datagram was ACCEPTED FOR SENDING — NOT that the world processed it. Failures arrive ASYNCHRONOUSLY as GenericErrorResponse on udpNotifications, correlated by the request sequenceNumber (correlation only — not an idempotency key; the server does not dedupe replays). */
|
|
4589
4589
|
sendClientEvent: Scalars['Boolean']['output'];
|
|
4590
|
+
/** Publish a message to a channel that only reaches members near an origin chunk: a member receives it, as an ordinary ChannelMessageNotification on udpNotifications, when one of its live actors is in the same app within maxDistance chunks of input.chunk (straight-line distance between chunk coordinates, boundary included). A member with no live actor does not receive it. Requires a bearer game token and the channel send_messages permission, as for sendChannelMessage; the origin app must be the token’s app. Opens a UDP proxy session automatically if none exists. The sender receives no echo. Returns Boolean! that is true only when the datagram was ACCEPTED FOR SENDING — NOT confirmation of delivery; failures arrive ASYNCHRONOUSLY as GenericErrorResponse on udpNotifications (UNAUTHORIZED without the send right, INVALID_APP_ID for another app), correlated by the request sequenceNumber (correlation only — not an idempotency key; the server does not dedupe replays). */
|
|
4591
|
+
sendRangedChannelMessage: Scalars['Boolean']['output'];
|
|
4590
4592
|
/** Send a direct actor-to-actor message, delivered only to the actor identified by targetUuid (NOT broadcast to nearby actors). The sender must know the destination actor’s current chunk. Requires a bearer game token; opens a UDP proxy session automatically if none exists. The target receives a SingleActorMessageNotification on udpNotifications; the sender receives no echo. Returns Boolean! that is true only when the datagram was ACCEPTED FOR SENDING — NOT confirmation of delivery; failures arrive ASYNCHRONOUSLY as GenericErrorResponse on udpNotifications, correlated by the request sequenceNumber (correlation only — not an idempotency key; the server does not dedupe replays). */
|
|
4591
4593
|
sendSingleActorMessage: Scalars['Boolean']['output'];
|
|
4592
4594
|
/** Operator only (is_operator). Sends a plain test message to one address and returns the SES message id. SIDE EFFECTS: a real outbound email billed to the shared SES identity, and a `send` row in email_events. Prefer the AWS mailbox simulator (success@ / bounce@ / complaint@simulator.amazonses.com), which exercises the whole path without touching a real inbox or a real reputation. `sent: true` with `simulated: true` means SEND_EMAILS is off and nothing left the building -- read both fields. */
|
|
@@ -5208,6 +5210,9 @@ export type MutationSendChannelMessageArgs = {
|
|
|
5208
5210
|
export type MutationSendClientEventArgs = {
|
|
5209
5211
|
input: ClientEventNotificationInput;
|
|
5210
5212
|
};
|
|
5213
|
+
export type MutationSendRangedChannelMessageArgs = {
|
|
5214
|
+
input: RangedChannelMessageInput;
|
|
5215
|
+
};
|
|
5211
5216
|
export type MutationSendSingleActorMessageArgs = {
|
|
5212
5217
|
input: SingleActorMessageInput;
|
|
5213
5218
|
};
|
|
@@ -7149,6 +7154,23 @@ export type QueryWalletTransactionsConnectionArgs = {
|
|
|
7149
7154
|
first?: InputMaybe<Scalars['Int']['input']>;
|
|
7150
7155
|
orgId: Scalars['BigInt']['input'];
|
|
7151
7156
|
};
|
|
7157
|
+
/** Input for publishing a channel message that only reaches members near an origin chunk. A member receives it when one of its live actors is in the same app within maxDistance chunks of the origin, measured as the straight-line (Euclidean) distance between chunk coordinates, boundary included; a member with no live actor does not receive it. Members receive an ordinary ChannelMessageNotification. The sender must have the channel send_messages permission, exactly as for sendChannelMessage. */
|
|
7158
|
+
export type RangedChannelMessageInput = {
|
|
7159
|
+
/** The app the origin chunk is in. Must be the app this token is scoped to (the game server answers INVALID_APP_ID otherwise). */
|
|
7160
|
+
appId: Scalars['BigInt']['input'];
|
|
7161
|
+
/** The channel id (groups.group_id) to publish to. */
|
|
7162
|
+
channelId: Scalars['BigInt']['input'];
|
|
7163
|
+
/** The origin chunk distance is measured from, usually the chunk of the sending actor. A chunk is a 16x16x16 voxel cube. */
|
|
7164
|
+
chunk: ChunkCoordinatesInput;
|
|
7165
|
+
/** Largest straight-line distance from the origin chunk, in chunks, at which a member still receives the message: 0 (the origin chunk only) to 2147483647. Not capped at 8 and not the Chebyshev ring count spatial sends use. */
|
|
7166
|
+
maxDistance: Scalars['Int']['input'];
|
|
7167
|
+
/** The message payload, base64-encoded. Opaque to the server; decode per your application protocol. Max 1024 bytes. */
|
|
7168
|
+
payload: Scalars['String']['input'];
|
|
7169
|
+
/** Client-assigned correlation id for this datagram: a uint8 (0-255) that wraps at gameClientBootstrap.sequenceNumberModulo (256); defaults to 0 if omitted. For CORRELATION ONLY — it is NOT an idempotency key and the server does not dedupe replays. Echoed on any GenericErrorResponse for this send, delivered on the udpNotifications subscription. */
|
|
7170
|
+
sequenceNumber?: InputMaybe<Scalars['Int']['input']>;
|
|
7171
|
+
/** The sender's actor UUID (your own actor's UUID). Must be exactly 32 bytes when encoded as UTF-8. */
|
|
7172
|
+
uuid: Scalars['String']['input'];
|
|
7173
|
+
};
|
|
7152
7174
|
export type RateCardBandInput = {
|
|
7153
7175
|
/** Cents per the row's unitQuantity raw units inside this band: >= 0, at most six decimals, and never more than the band below it. */
|
|
7154
7176
|
priceCents: Scalars['Float']['input'];
|