@crowdedkingdomstudios/crowdyjs 1.0.2 → 1.0.4
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 +289 -131
- package/dist/client.js +27 -27
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/subscriptions.d.ts.map +1 -1
- package/dist/subscriptions.js +23 -94
- package/dist/types.d.ts +38 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# CrowdyJS SDK
|
|
2
2
|
|
|
3
|
-
Client SDK for Crowded Kingdoms GraphQL API with UDP proxy support.
|
|
3
|
+
Client SDK for the Crowded Kingdoms GraphQL API with UDP proxy support.
|
|
4
|
+
Handles authentication, real-time subscriptions, and all game-server
|
|
5
|
+
communication through a single `CrowdyClient` instance.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -8,211 +10,367 @@ Client SDK for Crowded Kingdoms GraphQL API with UDP proxy support.
|
|
|
8
10
|
npm install @crowdedkingdomstudios/crowdyjs
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
|
|
13
|
+
### Node.js
|
|
14
|
+
|
|
15
|
+
The SDK uses the browser-native `WebSocket` API. In Node.js you need a
|
|
16
|
+
polyfill such as the `ws` package:
|
|
17
|
+
|
|
12
18
|
```bash
|
|
13
|
-
npm
|
|
19
|
+
npm install ws
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import WebSocket from 'ws';
|
|
24
|
+
globalThis.WebSocket = WebSocket;
|
|
14
25
|
```
|
|
15
26
|
|
|
16
|
-
|
|
27
|
+
Place this **before** importing `CrowdyClient`.
|
|
17
28
|
|
|
18
|
-
###
|
|
29
|
+
### Browser
|
|
30
|
+
|
|
31
|
+
No extra setup needed -- the SDK uses the built-in `WebSocket`.
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
19
34
|
|
|
20
35
|
```javascript
|
|
21
36
|
import { CrowdyClient } from '@crowdedkingdomstudios/crowdyjs';
|
|
22
37
|
|
|
23
38
|
const client = new CrowdyClient({
|
|
24
|
-
graphqlEndpoint: '
|
|
25
|
-
wsEndpoint: '
|
|
39
|
+
graphqlEndpoint: 'https://your-server.com/graphql',
|
|
40
|
+
wsEndpoint: 'wss://your-server.com/graphql',
|
|
26
41
|
});
|
|
27
42
|
```
|
|
28
43
|
|
|
29
|
-
|
|
44
|
+
If omitted, both endpoints default to `localhost:3000/graphql`.
|
|
45
|
+
|
|
46
|
+
## Connection Lifecycle
|
|
47
|
+
|
|
48
|
+
The SDK follows a four-step lifecycle that matches the server protocol:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
1. Login --> obtain a game token
|
|
52
|
+
2. Subscribe --> auto-opens UDP proxy session
|
|
53
|
+
3. Register --> tell the game server your chunk position
|
|
54
|
+
4. Send updates --> replicated to other clients in range
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### 1. Login
|
|
30
58
|
|
|
31
59
|
```javascript
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
60
|
+
const auth = await client.login('user@example.com', 'password');
|
|
61
|
+
// auth.token -- 64-char hex game token (set automatically)
|
|
62
|
+
// auth.user.email -- logged-in user
|
|
63
|
+
```
|
|
35
64
|
|
|
36
|
-
|
|
37
|
-
|
|
65
|
+
Or register a new account:
|
|
66
|
+
|
|
67
|
+
```javascript
|
|
68
|
+
const auth = await client.register('user@example.com', 'password', 'MyGamertag');
|
|
38
69
|
```
|
|
39
70
|
|
|
40
|
-
###
|
|
71
|
+
### 2. Subscribe to Notifications
|
|
72
|
+
|
|
73
|
+
Register one or more notification handlers. The first handler automatically
|
|
74
|
+
opens a WebSocket subscription and a UDP proxy session to the game server --
|
|
75
|
+
no explicit `connectUdpProxy()` call is needed.
|
|
41
76
|
|
|
42
77
|
```javascript
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
console.log('
|
|
78
|
+
const unsub = client.onActorUpdate((notification) => {
|
|
79
|
+
console.log('Actor:', notification.uuid);
|
|
80
|
+
console.log('State:', notification.state);
|
|
81
|
+
console.log('Chunk:', notification.chunkX, notification.chunkY, notification.chunkZ);
|
|
82
|
+
console.log('Time:', notification.epochMillis);
|
|
83
|
+
});
|
|
84
|
+
```
|
|
46
85
|
|
|
47
|
-
|
|
48
|
-
const status = await client.getConnectionStatus();
|
|
86
|
+
Handlers are unsubscribed by calling the returned function:
|
|
49
87
|
|
|
50
|
-
|
|
51
|
-
|
|
88
|
+
```javascript
|
|
89
|
+
unsub(); // stop receiving ActorUpdateNotification
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
When all handlers are removed the WebSocket is closed automatically.
|
|
93
|
+
|
|
94
|
+
### 3. Register in a Chunk
|
|
95
|
+
|
|
96
|
+
Before other clients can see you, send an initial actor update so the game
|
|
97
|
+
server knows which chunk you occupy. Use a minimal base64 payload (the
|
|
98
|
+
server requires a non-empty `state`):
|
|
99
|
+
|
|
100
|
+
```javascript
|
|
101
|
+
const MY_UUID = 'aaaaaaaabbbbccccddddeeeeeeeeeeee'; // exactly 32 bytes UTF-8
|
|
102
|
+
|
|
103
|
+
await client.sendActorUpdate({
|
|
104
|
+
mapId: 0,
|
|
105
|
+
chunk: { x: 0, y: 0, z: 0 },
|
|
106
|
+
distance: 8,
|
|
107
|
+
uuid: MY_UUID,
|
|
108
|
+
state: 'AA==', // minimal base64 payload for registration
|
|
109
|
+
sequenceNumber: 1,
|
|
110
|
+
});
|
|
52
111
|
```
|
|
53
112
|
|
|
54
|
-
|
|
113
|
+
Every client in the same chunk must do this. After registration, the game
|
|
114
|
+
server fans out subsequent updates to all registered clients in range.
|
|
115
|
+
|
|
116
|
+
### 4. Send Actor Updates
|
|
55
117
|
|
|
56
118
|
```javascript
|
|
57
|
-
//
|
|
119
|
+
// Build your binary state and base64-encode it
|
|
58
120
|
const stateBuffer = new ArrayBuffer(96);
|
|
59
121
|
const view = new DataView(stateBuffer);
|
|
60
|
-
view.setFloat32(0,
|
|
61
|
-
view.setFloat32(4,
|
|
62
|
-
|
|
122
|
+
view.setFloat32(0, posX, true);
|
|
123
|
+
view.setFloat32(4, posY, true);
|
|
124
|
+
view.setFloat32(8, posZ, true);
|
|
125
|
+
// ... fill remaining fields
|
|
63
126
|
|
|
64
|
-
// Convert to base64
|
|
65
127
|
const base64State = btoa(String.fromCharCode(...new Uint8Array(stateBuffer)));
|
|
66
128
|
|
|
67
|
-
// Send update
|
|
68
129
|
await client.sendActorUpdate({
|
|
69
|
-
mapId:
|
|
70
|
-
chunk: { x:
|
|
71
|
-
|
|
130
|
+
mapId: 0,
|
|
131
|
+
chunk: { x: 0, y: 0, z: 0 },
|
|
132
|
+
distance: 8,
|
|
133
|
+
decayRate: 0,
|
|
134
|
+
uuid: MY_UUID,
|
|
72
135
|
state: base64State,
|
|
136
|
+
sequenceNumber: 2,
|
|
73
137
|
});
|
|
74
138
|
```
|
|
75
139
|
|
|
76
|
-
###
|
|
140
|
+
### 5. Disconnect
|
|
141
|
+
|
|
142
|
+
```javascript
|
|
143
|
+
await client.disconnectUdpProxy(); // release the UDP session
|
|
144
|
+
client.close(); // close WebSocket + clear state
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Unsubscribing from notifications stops delivery but does **not** release
|
|
148
|
+
the UDP session. Call `disconnectUdpProxy()` explicitly, or the server
|
|
149
|
+
will release it after 30 seconds of inactivity.
|
|
150
|
+
|
|
151
|
+
## Subscription Handlers
|
|
77
152
|
|
|
78
|
-
|
|
153
|
+
All spatial notification types share a uniform header:
|
|
154
|
+
|
|
155
|
+
| Field | Type | Description |
|
|
156
|
+
|-------|------|-------------|
|
|
157
|
+
| `mapId` | `string` | Map / chunk-W coordinate |
|
|
158
|
+
| `chunkX` | `string` | Chunk X coordinate |
|
|
159
|
+
| `chunkY` | `string` | Chunk Y coordinate |
|
|
160
|
+
| `chunkZ` | `string` | Chunk Z coordinate |
|
|
161
|
+
| `distance` | `number` | Replication distance (0-8) |
|
|
162
|
+
| `decayRate` | `number` | Delivery decay (0-5) |
|
|
163
|
+
| `uuid` | `string` | 32-byte sender UUID |
|
|
164
|
+
| `sequenceNumber` | `number` | uint8 (0-255), wraps |
|
|
165
|
+
| `epochMillis` | `string` | Server UTC timestamp in ms |
|
|
166
|
+
|
|
167
|
+
Each handler receives a fully-typed notification object:
|
|
79
168
|
|
|
80
169
|
```javascript
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
});
|
|
170
|
+
client.onActorUpdate((n) => { /* n: ActorUpdateNotification -- adds: state */ });
|
|
171
|
+
client.onActorUpdateResponse((n) => { /* n: ActorUpdateResponse */ });
|
|
172
|
+
client.onVoxelUpdate((n) => { /* n: VoxelUpdateNotification -- adds: voxelX/Y/Z, voxelType, voxelState */ });
|
|
173
|
+
client.onVoxelUpdateResponse((n) => { /* n: VoxelUpdateResponse */ });
|
|
174
|
+
client.onClientAudio((n) => { /* n: ClientAudioNotification -- adds: audioData */ });
|
|
175
|
+
client.onClientText((n) => { /* n: ClientTextNotification -- adds: text */ });
|
|
176
|
+
client.onClientEvent((n) => { /* n: ClientEventNotification -- adds: eventType, state */ });
|
|
177
|
+
client.onServerEvent((n) => { /* n: ServerEventNotification -- adds: eventType, state */ });
|
|
178
|
+
client.onGenericError((e) => { /* e: GenericErrorResponse -- sequenceNumber, errorCode only */ });
|
|
179
|
+
```
|
|
86
180
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
// response is typed as ActorUpdateResponse
|
|
90
|
-
if (response.errorCode === 'NO_ERROR') {
|
|
91
|
-
console.log('Update successful');
|
|
92
|
-
}
|
|
93
|
-
});
|
|
181
|
+
`GenericErrorResponse` is the only type without the spatial header; it has
|
|
182
|
+
just `sequenceNumber` and `errorCode`.
|
|
94
183
|
|
|
95
|
-
|
|
96
|
-
const unsubscribe3 = client.onVoxelUpdate((notification) => {
|
|
97
|
-
// notification is typed as VoxelUpdateNotification
|
|
98
|
-
});
|
|
184
|
+
## Input Parameters
|
|
99
185
|
|
|
100
|
-
|
|
101
|
-
const unsubscribe4 = client.onClientAudio((notification) => {
|
|
102
|
-
// notification is typed as ClientAudioNotification
|
|
103
|
-
});
|
|
186
|
+
### Common fields
|
|
104
187
|
|
|
105
|
-
|
|
106
|
-
const unsubscribe5 = client.onClientText((notification) => {
|
|
107
|
-
// notification is typed as ClientTextNotification
|
|
108
|
-
});
|
|
188
|
+
All mutation inputs share these fields:
|
|
109
189
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
})
|
|
190
|
+
| Field | Type | Required | Default | Description |
|
|
191
|
+
|-------|------|----------|---------|-------------|
|
|
192
|
+
| `mapId` | `number` | yes | -- | Map / chunk-W coordinate |
|
|
193
|
+
| `chunk` | `{ x, y, z }` | yes | -- | Chunk coordinates (numbers) |
|
|
194
|
+
| `uuid` | `string` | yes | -- | Your 32-byte UUID |
|
|
195
|
+
| `distance` | `number` | no | `8` | Replication range (0-8 chunks, Chebyshev) |
|
|
196
|
+
| `decayRate` | `number` | no | `0` | Delivery decay (see table below) |
|
|
197
|
+
| `sequenceNumber` | `number` | no | `0` | uint8 (0-255) for correlation |
|
|
114
198
|
|
|
115
|
-
|
|
116
|
-
const unsubscribe7 = client.onServerEvent((notification) => {
|
|
117
|
-
// notification is typed as ServerEventNotification
|
|
118
|
-
});
|
|
199
|
+
### `decayRate` values
|
|
119
200
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
201
|
+
| Value | Name | Behavior |
|
|
202
|
+
|-------|------|----------|
|
|
203
|
+
| 0 | None | All clients within `distance` receive every message |
|
|
204
|
+
| 1 | Exponential | Each ring receives half the messages of the previous ring |
|
|
205
|
+
| 2 | Linear 50% | Furthest ring receives 50% of messages |
|
|
206
|
+
| 3 | Linear 25% | Furthest ring receives 25% of messages |
|
|
207
|
+
| 4 | Linear 10% | Furthest ring receives 10% of messages |
|
|
208
|
+
| 5 | Linear 5% | Furthest ring receives 5% of messages |
|
|
209
|
+
|
|
210
|
+
### `sendActorUpdate`
|
|
211
|
+
|
|
212
|
+
| Field | Type | Description |
|
|
213
|
+
|-------|------|-------------|
|
|
214
|
+
| `state` | `string` | Base64-encoded binary state (must be non-empty) |
|
|
215
|
+
|
|
216
|
+
### `sendVoxelUpdate`
|
|
217
|
+
|
|
218
|
+
| Field | Type | Description |
|
|
219
|
+
|-------|------|-------------|
|
|
220
|
+
| `voxel` | `{ x, y, z }` | Voxel position within the chunk |
|
|
221
|
+
| `voxelType` | `number` | Voxel type ID |
|
|
222
|
+
| `voxelState` | `string` | Base64-encoded voxel state |
|
|
223
|
+
|
|
224
|
+
### `sendAudioPacket`
|
|
225
|
+
|
|
226
|
+
| Field | Type | Description |
|
|
227
|
+
|-------|------|-------------|
|
|
228
|
+
| `audioData` | `string` | Base64-encoded compressed audio |
|
|
229
|
+
|
|
230
|
+
### `sendTextPacket`
|
|
231
|
+
|
|
232
|
+
| Field | Type | Description |
|
|
233
|
+
|-------|------|-------------|
|
|
234
|
+
| `text` | `string` | Chat message text |
|
|
125
235
|
|
|
126
|
-
###
|
|
236
|
+
### `sendClientEvent`
|
|
237
|
+
|
|
238
|
+
| Field | Type | Description |
|
|
239
|
+
|-------|------|-------------|
|
|
240
|
+
| `eventType` | `number` | Custom event type ID |
|
|
241
|
+
| `state` | `string` | Base64-encoded event state |
|
|
242
|
+
|
|
243
|
+
## Complete Example
|
|
127
244
|
|
|
128
245
|
```javascript
|
|
246
|
+
import WebSocket from 'ws';
|
|
247
|
+
globalThis.WebSocket = WebSocket;
|
|
248
|
+
|
|
129
249
|
import { CrowdyClient } from '@crowdedkingdomstudios/crowdyjs';
|
|
130
250
|
|
|
131
251
|
const client = new CrowdyClient({
|
|
132
|
-
graphqlEndpoint: '
|
|
133
|
-
wsEndpoint: '
|
|
252
|
+
graphqlEndpoint: 'https://your-server.com/graphql',
|
|
253
|
+
wsEndpoint: 'wss://your-server.com/graphql',
|
|
134
254
|
});
|
|
135
255
|
|
|
136
|
-
|
|
256
|
+
const MY_UUID = 'aaaaaaaabbbbccccddddeeeeeeeeeeee';
|
|
257
|
+
|
|
258
|
+
// 1. Login
|
|
137
259
|
await client.login('user@example.com', 'password');
|
|
138
260
|
|
|
139
|
-
//
|
|
140
|
-
|
|
261
|
+
// 2. Subscribe (auto-opens UDP proxy session)
|
|
262
|
+
const unsubActors = client.onActorUpdate((n) => {
|
|
263
|
+
console.log(`Actor ${n.uuid} at chunk (${n.chunkX},${n.chunkY},${n.chunkZ})`);
|
|
264
|
+
console.log(` state=${n.state} seq=${n.sequenceNumber} t=${n.epochMillis}`);
|
|
265
|
+
});
|
|
141
266
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.log('Actor update:', notification.uuid);
|
|
145
|
-
// Handle the update...
|
|
267
|
+
const unsubErrors = client.onGenericError((e) => {
|
|
268
|
+
console.error(`Error: ${e.errorCode} (seq ${e.sequenceNumber})`);
|
|
146
269
|
});
|
|
147
270
|
|
|
148
|
-
//
|
|
149
|
-
|
|
271
|
+
// 3. Register in chunk
|
|
272
|
+
await client.sendActorUpdate({
|
|
273
|
+
mapId: 0,
|
|
274
|
+
chunk: { x: 0, y: 0, z: 0 },
|
|
275
|
+
distance: 8,
|
|
276
|
+
uuid: MY_UUID,
|
|
277
|
+
state: 'AA==',
|
|
278
|
+
sequenceNumber: 1,
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// 4. Send updates in a loop
|
|
282
|
+
let seq = 2;
|
|
283
|
+
const interval = setInterval(async () => {
|
|
284
|
+
const buf = new Uint8Array(96);
|
|
285
|
+
crypto.getRandomValues(buf);
|
|
286
|
+
const state = btoa(String.fromCharCode(...buf));
|
|
287
|
+
|
|
150
288
|
await client.sendActorUpdate({
|
|
151
|
-
mapId:
|
|
152
|
-
chunk: { x:
|
|
153
|
-
|
|
154
|
-
|
|
289
|
+
mapId: 0,
|
|
290
|
+
chunk: { x: 0, y: 0, z: 0 },
|
|
291
|
+
distance: 8,
|
|
292
|
+
uuid: MY_UUID,
|
|
293
|
+
state,
|
|
294
|
+
sequenceNumber: seq++ % 256,
|
|
155
295
|
});
|
|
156
296
|
}, 100);
|
|
157
297
|
|
|
158
|
-
// Cleanup
|
|
159
|
-
|
|
298
|
+
// 5. Cleanup
|
|
299
|
+
clearInterval(interval);
|
|
300
|
+
unsubActors();
|
|
301
|
+
unsubErrors();
|
|
160
302
|
await client.disconnectUdpProxy();
|
|
161
303
|
client.close();
|
|
162
304
|
```
|
|
163
305
|
|
|
164
306
|
## API Reference
|
|
165
307
|
|
|
166
|
-
###
|
|
167
|
-
|
|
168
|
-
Main client class for interacting with the API.
|
|
169
|
-
|
|
170
|
-
#### Constructor
|
|
308
|
+
### Constructor
|
|
171
309
|
|
|
172
310
|
```typescript
|
|
173
311
|
new CrowdyClient(config?: CrowdyClientConfig)
|
|
174
312
|
```
|
|
175
313
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
#### Methods
|
|
182
|
-
|
|
183
|
-
**Authentication:**
|
|
184
|
-
- `login(email: string, password: string): Promise<AuthResponse>`
|
|
185
|
-
- `register(email: string, password: string, gamertag?: string): Promise<AuthResponse>`
|
|
186
|
-
- `getAuthToken(): string | null`
|
|
187
|
-
|
|
188
|
-
**UDP Proxy:**
|
|
189
|
-
- `connectUdpProxy(): Promise<UdpProxyConnectionStatus>`
|
|
190
|
-
- `disconnectUdpProxy(): Promise<boolean>`
|
|
191
|
-
- `getConnectionStatus(): Promise<UdpProxyConnectionStatus>`
|
|
314
|
+
| Option | Type | Default | Description |
|
|
315
|
+
|--------|------|---------|-------------|
|
|
316
|
+
| `graphqlEndpoint` | `string` | `http://localhost:3000/graphql` | HTTP endpoint for mutations/queries |
|
|
317
|
+
| `wsEndpoint` | `string` | `ws://localhost:3000/graphql` | WebSocket endpoint for subscriptions |
|
|
318
|
+
| `timeout` | `number` | `60000` | HTTP request timeout in ms |
|
|
192
319
|
|
|
193
|
-
|
|
194
|
-
- `sendActorUpdate(input: ActorUpdateRequestInput): Promise<boolean>`
|
|
195
|
-
- `sendVoxelUpdate(input: VoxelUpdateRequestInput): Promise<boolean>`
|
|
196
|
-
- `sendAudioPacket(input: ClientAudioPacketInput): Promise<boolean>`
|
|
197
|
-
- `sendTextPacket(input: ClientTextPacketInput): Promise<boolean>`
|
|
198
|
-
- `sendClientEvent(input: ClientEventNotificationInput): Promise<boolean>`
|
|
199
|
-
|
|
200
|
-
**Subscriptions:**
|
|
201
|
-
- `onActorUpdate(handler: ActorUpdateHandler): UnsubscribeFn`
|
|
202
|
-
- `onActorUpdateResponse(handler: ActorUpdateResponseHandler): UnsubscribeFn`
|
|
203
|
-
- `onVoxelUpdate(handler: VoxelUpdateHandler): UnsubscribeFn`
|
|
204
|
-
- `onVoxelUpdateResponse(handler: VoxelUpdateResponseHandler): UnsubscribeFn`
|
|
205
|
-
- `onClientAudio(handler: ClientAudioHandler): UnsubscribeFn`
|
|
206
|
-
- `onClientText(handler: ClientTextHandler): UnsubscribeFn`
|
|
207
|
-
- `onClientEvent(handler: ClientEventHandler): UnsubscribeFn`
|
|
208
|
-
- `onServerEvent(handler: ServerEventHandler): UnsubscribeFn`
|
|
209
|
-
|
|
210
|
-
**Cleanup:**
|
|
211
|
-
- `close(): void` - Closes all subscriptions and cleans up
|
|
212
|
-
|
|
213
|
-
## TypeScript Support
|
|
320
|
+
### Authentication
|
|
214
321
|
|
|
215
|
-
|
|
322
|
+
| Method | Returns | Description |
|
|
323
|
+
|--------|---------|-------------|
|
|
324
|
+
| `login(email, password)` | `Promise<AuthResponse>` | Login and store the game token |
|
|
325
|
+
| `register(email, password, gamertag?)` | `Promise<AuthResponse>` | Register and store the game token |
|
|
326
|
+
| `getAuthToken()` | `string \| null` | Get the current game token |
|
|
327
|
+
|
|
328
|
+
### UDP Proxy
|
|
329
|
+
|
|
330
|
+
| Method | Returns | Description |
|
|
331
|
+
|--------|---------|-------------|
|
|
332
|
+
| `connectUdpProxy()` | `Promise<UdpProxyConnectionStatus>` | Explicitly open a UDP session (optional) |
|
|
333
|
+
| `disconnectUdpProxy()` | `Promise<boolean>` | Release the UDP session |
|
|
334
|
+
| `getConnectionStatus()` | `Promise<UdpProxyConnectionStatus>` | Check if a UDP session is active |
|
|
335
|
+
|
|
336
|
+
### Mutations
|
|
337
|
+
|
|
338
|
+
| Method | Returns | Description |
|
|
339
|
+
|--------|---------|-------------|
|
|
340
|
+
| `sendActorUpdate(input)` | `Promise<boolean>` | Send an actor state update |
|
|
341
|
+
| `sendVoxelUpdate(input)` | `Promise<boolean>` | Modify a voxel in a chunk |
|
|
342
|
+
| `sendAudioPacket(input)` | `Promise<boolean>` | Send voice audio data |
|
|
343
|
+
| `sendTextPacket(input)` | `Promise<boolean>` | Send chat text |
|
|
344
|
+
| `sendClientEvent(input)` | `Promise<boolean>` | Send a custom event |
|
|
345
|
+
|
|
346
|
+
### Subscriptions
|
|
347
|
+
|
|
348
|
+
| Method | Handler receives | Description |
|
|
349
|
+
|--------|-----------------|-------------|
|
|
350
|
+
| `onActorUpdate(handler)` | `ActorUpdateNotification` | Another client's actor state |
|
|
351
|
+
| `onActorUpdateResponse(handler)` | `ActorUpdateResponse` | Server ack for your actor update |
|
|
352
|
+
| `onVoxelUpdate(handler)` | `VoxelUpdateNotification` | A voxel was modified |
|
|
353
|
+
| `onVoxelUpdateResponse(handler)` | `VoxelUpdateResponse` | Server ack for your voxel update |
|
|
354
|
+
| `onClientAudio(handler)` | `ClientAudioNotification` | Voice audio from another client |
|
|
355
|
+
| `onClientText(handler)` | `ClientTextNotification` | Chat text from another client |
|
|
356
|
+
| `onClientEvent(handler)` | `ClientEventNotification` | Custom event from another client |
|
|
357
|
+
| `onServerEvent(handler)` | `ServerEventNotification` | Event from the game server |
|
|
358
|
+
| `onGenericError(handler)` | `GenericErrorResponse` | Error from the server |
|
|
359
|
+
|
|
360
|
+
All subscription methods return an `UnsubscribeFn` -- call it to remove
|
|
361
|
+
the handler.
|
|
362
|
+
|
|
363
|
+
### Cleanup
|
|
364
|
+
|
|
365
|
+
| Method | Description |
|
|
366
|
+
|--------|-------------|
|
|
367
|
+
| `close()` | Close the WebSocket, remove all handlers, clear auth state |
|
|
368
|
+
|
|
369
|
+
## TypeScript
|
|
370
|
+
|
|
371
|
+
The SDK is written in TypeScript and ships type declarations. All
|
|
372
|
+
notification interfaces, input types, and handler signatures are fully
|
|
373
|
+
typed for IDE autocomplete and compile-time safety.
|
|
216
374
|
|
|
217
375
|
## License
|
|
218
376
|
|
package/dist/client.js
CHANGED
|
@@ -101,7 +101,7 @@ export class GraphQLClient {
|
|
|
101
101
|
async connectUdpProxy() {
|
|
102
102
|
const data = await this.query(`
|
|
103
103
|
mutation ConnectUdpProxy {
|
|
104
|
-
connectUdpProxy
|
|
104
|
+
connectUdpProxy {
|
|
105
105
|
connected
|
|
106
106
|
serverIp6
|
|
107
107
|
serverClientPort
|
|
@@ -134,17 +134,17 @@ export class GraphQLClient {
|
|
|
134
134
|
}
|
|
135
135
|
async sendActorUpdate(input) {
|
|
136
136
|
const normalizedInput = {
|
|
137
|
-
mapId: String(
|
|
137
|
+
mapId: String(input.mapId),
|
|
138
138
|
chunk: {
|
|
139
|
-
x: String(
|
|
140
|
-
y: String(
|
|
141
|
-
z: String(
|
|
139
|
+
x: String(input.chunk.x),
|
|
140
|
+
y: String(input.chunk.y),
|
|
141
|
+
z: String(input.chunk.z),
|
|
142
142
|
},
|
|
143
143
|
uuid: String(input.uuid),
|
|
144
144
|
state: String(input.state),
|
|
145
145
|
distance: input.distance ?? 8,
|
|
146
|
-
decayRate: input.decayRate ??
|
|
147
|
-
|
|
146
|
+
decayRate: input.decayRate ?? 0,
|
|
147
|
+
sequenceNumber: input.sequenceNumber ?? 0,
|
|
148
148
|
};
|
|
149
149
|
const data = await this.query(`
|
|
150
150
|
mutation SendActorUpdate($input: ActorUpdateRequestInput!) {
|
|
@@ -155,11 +155,11 @@ export class GraphQLClient {
|
|
|
155
155
|
}
|
|
156
156
|
async sendVoxelUpdate(input) {
|
|
157
157
|
const normalizedInput = {
|
|
158
|
-
mapId: String(
|
|
158
|
+
mapId: String(input.mapId),
|
|
159
159
|
chunk: {
|
|
160
|
-
x: String(
|
|
161
|
-
y: String(
|
|
162
|
-
z: String(
|
|
160
|
+
x: String(input.chunk.x),
|
|
161
|
+
y: String(input.chunk.y),
|
|
162
|
+
z: String(input.chunk.z),
|
|
163
163
|
},
|
|
164
164
|
uuid: String(input.uuid),
|
|
165
165
|
voxel: input.voxel,
|
|
@@ -167,7 +167,7 @@ export class GraphQLClient {
|
|
|
167
167
|
voxelState: String(input.voxelState),
|
|
168
168
|
distance: input.distance ?? 8,
|
|
169
169
|
decayRate: input.decayRate ?? 0,
|
|
170
|
-
|
|
170
|
+
sequenceNumber: input.sequenceNumber ?? 0,
|
|
171
171
|
};
|
|
172
172
|
const data = await this.query(`
|
|
173
173
|
mutation SendVoxelUpdate($input: VoxelUpdateRequestInput!) {
|
|
@@ -178,17 +178,17 @@ export class GraphQLClient {
|
|
|
178
178
|
}
|
|
179
179
|
async sendAudioPacket(input) {
|
|
180
180
|
const normalizedInput = {
|
|
181
|
-
mapId: String(
|
|
181
|
+
mapId: String(input.mapId),
|
|
182
182
|
chunk: {
|
|
183
|
-
x: String(
|
|
184
|
-
y: String(
|
|
185
|
-
z: String(
|
|
183
|
+
x: String(input.chunk.x),
|
|
184
|
+
y: String(input.chunk.y),
|
|
185
|
+
z: String(input.chunk.z),
|
|
186
186
|
},
|
|
187
187
|
uuid: String(input.uuid),
|
|
188
188
|
audioData: String(input.audioData),
|
|
189
189
|
distance: input.distance ?? 1,
|
|
190
190
|
decayRate: input.decayRate ?? 0,
|
|
191
|
-
|
|
191
|
+
sequenceNumber: input.sequenceNumber ?? 0,
|
|
192
192
|
};
|
|
193
193
|
const data = await this.query(`
|
|
194
194
|
mutation SendAudioPacket($input: ClientAudioPacketInput!) {
|
|
@@ -199,17 +199,17 @@ export class GraphQLClient {
|
|
|
199
199
|
}
|
|
200
200
|
async sendTextPacket(input) {
|
|
201
201
|
const normalizedInput = {
|
|
202
|
-
mapId: String(
|
|
202
|
+
mapId: String(input.mapId),
|
|
203
203
|
chunk: {
|
|
204
|
-
x: String(
|
|
205
|
-
y: String(
|
|
206
|
-
z: String(
|
|
204
|
+
x: String(input.chunk.x),
|
|
205
|
+
y: String(input.chunk.y),
|
|
206
|
+
z: String(input.chunk.z),
|
|
207
207
|
},
|
|
208
208
|
uuid: String(input.uuid),
|
|
209
209
|
text: String(input.text),
|
|
210
210
|
distance: input.distance ?? 1,
|
|
211
211
|
decayRate: input.decayRate ?? 0,
|
|
212
|
-
|
|
212
|
+
sequenceNumber: input.sequenceNumber ?? 0,
|
|
213
213
|
};
|
|
214
214
|
const data = await this.query(`
|
|
215
215
|
mutation SendTextPacket($input: ClientTextPacketInput!) {
|
|
@@ -220,18 +220,18 @@ export class GraphQLClient {
|
|
|
220
220
|
}
|
|
221
221
|
async sendClientEvent(input) {
|
|
222
222
|
const normalizedInput = {
|
|
223
|
-
mapId: String(
|
|
223
|
+
mapId: String(input.mapId),
|
|
224
224
|
chunk: {
|
|
225
|
-
x: String(
|
|
226
|
-
y: String(
|
|
227
|
-
z: String(
|
|
225
|
+
x: String(input.chunk.x),
|
|
226
|
+
y: String(input.chunk.y),
|
|
227
|
+
z: String(input.chunk.z),
|
|
228
228
|
},
|
|
229
229
|
uuid: String(input.uuid),
|
|
230
230
|
eventType: input.eventType,
|
|
231
231
|
state: String(input.state),
|
|
232
232
|
distance: input.distance ?? 8,
|
|
233
233
|
decayRate: input.decayRate ?? 0,
|
|
234
|
-
|
|
234
|
+
sequenceNumber: input.sequenceNumber ?? 0,
|
|
235
235
|
};
|
|
236
236
|
const data = await this.query(`
|
|
237
237
|
mutation SendClientEvent($input: ClientEventNotificationInput!) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CrowdyJS SDK - Client SDK for Crowded Kingdoms GraphQL API
|
|
3
3
|
*/
|
|
4
|
+
export declare const VERSION = "1.0.3";
|
|
4
5
|
export { CrowdyClient } from './crowdy-client.js';
|
|
5
6
|
export type { CrowdyClientConfig, BigInt, ChunkCoordinates, ChunkCoordinatesInput, VoxelCoordinates, VoxelCoordinatesInput, UdpErrorCode, User, AuthResponse, UdpProxyConnectionStatus, ActorUpdateRequestInput, VoxelUpdateRequestInput, ClientAudioPacketInput, ClientTextPacketInput, ClientEventNotificationInput, ActorUpdateNotification, ActorUpdateResponse, VoxelUpdateNotification, VoxelUpdateResponse, ClientAudioNotification, ClientTextNotification, ClientEventNotification, ServerEventNotification, GenericErrorResponse, UdpNotification, ActorUpdateHandler, ActorUpdateResponseHandler, VoxelUpdateHandler, VoxelUpdateResponseHandler, ClientAudioHandler, ClientTextHandler, ClientEventHandler, ServerEventHandler, GenericErrorHandler, UnsubscribeFn, } from './types.js';
|
|
6
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAEV,kBAAkB,EAElB,MAAM,EACN,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,IAAI,EACJ,YAAY,EACZ,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAE5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,EAEf,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAEV,kBAAkB,EAElB,MAAM,EACN,gBAAgB,EAChB,qBAAqB,EACrB,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,IAAI,EACJ,YAAY,EACZ,wBAAwB,EAExB,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,qBAAqB,EACrB,4BAA4B,EAE5B,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,oBAAoB,EACpB,eAAe,EAEf,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAEV,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAcpB,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAUd;IAEF,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAuB;gBAExB,MAAM,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO;IAIhD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIxC,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../src/subscriptions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAEV,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,0BAA0B,EAC1B,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAcpB,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAUd;IAEF,OAAO,CAAC,QAAQ,CAA0B;IAC1C,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,cAAc,CAAuB;IAC7C,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAuB;gBAExB,MAAM,GAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAO;IAIhD,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIxC,OAAO,CAAC,kBAAkB;IAU1B,OAAO,CAAC,iBAAiB;IAyHzB,OAAO,CAAC,kBAAkB;IAmB1B,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAYzD,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,GAAG,aAAa;IAYzE,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAYzD,qBAAqB,CAAC,OAAO,EAAE,0BAA0B,GAAG,aAAa;IAYzE,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAYzD,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,aAAa;IAYvD,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAYzD,aAAa,CAAC,OAAO,EAAE,kBAAkB,GAAG,aAAa;IAYzD,cAAc,CAAC,OAAO,EAAE,mBAAmB,GAAG,aAAa;IAY3D,OAAO,CAAC,wBAAwB;IAShC,KAAK,IAAI,IAAI;CAWd"}
|
package/dist/subscriptions.js
CHANGED
|
@@ -41,114 +41,43 @@ export class SubscriptionManager {
|
|
|
41
41
|
}
|
|
42
42
|
const wsUrl = this.wsEndpoint;
|
|
43
43
|
this.subscriptionId = 'udp-notifications-' + Date.now();
|
|
44
|
-
const ws = new WebSocket(wsUrl, 'graphql-ws');
|
|
44
|
+
const ws = new WebSocket(wsUrl, 'graphql-transport-ws');
|
|
45
45
|
this.wsClient = ws;
|
|
46
46
|
ws.onopen = () => {
|
|
47
47
|
ws.send(JSON.stringify({
|
|
48
48
|
type: 'connection_init',
|
|
49
49
|
payload: {
|
|
50
|
-
authorization: `Bearer ${this.token}`,
|
|
51
50
|
Authorization: `Bearer ${this.token}`,
|
|
52
51
|
},
|
|
53
52
|
}));
|
|
54
53
|
};
|
|
55
54
|
ws.onmessage = (event) => {
|
|
56
55
|
try {
|
|
57
|
-
const message = JSON.parse(event.data);
|
|
56
|
+
const message = JSON.parse(typeof event.data === 'string' ? event.data : '');
|
|
58
57
|
if (message.type === 'connection_ack') {
|
|
59
|
-
const
|
|
58
|
+
const subscribeMessage = {
|
|
60
59
|
id: this.subscriptionId,
|
|
61
|
-
type: '
|
|
60
|
+
type: 'subscribe',
|
|
62
61
|
payload: {
|
|
63
62
|
query: `subscription {
|
|
64
63
|
udpNotifications {
|
|
65
64
|
__typename
|
|
66
|
-
... on ActorUpdateNotification {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
... on
|
|
75
|
-
mapId
|
|
76
|
-
chunkX
|
|
77
|
-
chunkY
|
|
78
|
-
chunkZ
|
|
79
|
-
uuid
|
|
80
|
-
sequenceNumber
|
|
81
|
-
}
|
|
82
|
-
... on VoxelUpdateNotification {
|
|
83
|
-
mapId
|
|
84
|
-
chunkX
|
|
85
|
-
chunkY
|
|
86
|
-
chunkZ
|
|
87
|
-
uuid
|
|
88
|
-
voxelX
|
|
89
|
-
voxelY
|
|
90
|
-
voxelZ
|
|
91
|
-
voxelType
|
|
92
|
-
voxelState
|
|
93
|
-
}
|
|
94
|
-
... on VoxelUpdateResponse {
|
|
95
|
-
mapId
|
|
96
|
-
chunkX
|
|
97
|
-
chunkY
|
|
98
|
-
chunkZ
|
|
99
|
-
uuid
|
|
100
|
-
sequenceNumber
|
|
101
|
-
}
|
|
102
|
-
... on ClientAudioNotification {
|
|
103
|
-
mapId
|
|
104
|
-
chunkX
|
|
105
|
-
chunkY
|
|
106
|
-
chunkZ
|
|
107
|
-
uuid
|
|
108
|
-
audioData
|
|
109
|
-
}
|
|
110
|
-
... on ClientTextNotification {
|
|
111
|
-
mapId
|
|
112
|
-
chunkX
|
|
113
|
-
chunkY
|
|
114
|
-
chunkZ
|
|
115
|
-
uuid
|
|
116
|
-
text
|
|
117
|
-
}
|
|
118
|
-
... on ClientEventNotification {
|
|
119
|
-
mapId
|
|
120
|
-
chunkX
|
|
121
|
-
chunkY
|
|
122
|
-
chunkZ
|
|
123
|
-
uuid
|
|
124
|
-
eventType
|
|
125
|
-
state
|
|
126
|
-
}
|
|
127
|
-
... on ServerEventNotification {
|
|
128
|
-
mapId
|
|
129
|
-
chunkX
|
|
130
|
-
chunkY
|
|
131
|
-
chunkZ
|
|
132
|
-
uuid
|
|
133
|
-
eventType
|
|
134
|
-
state
|
|
135
|
-
}
|
|
136
|
-
... on GenericErrorResponse {
|
|
137
|
-
sequenceNumber
|
|
138
|
-
errorCode
|
|
139
|
-
}
|
|
65
|
+
... on ActorUpdateNotification { mapId chunkX chunkY chunkZ distance decayRate uuid state sequenceNumber epochMillis }
|
|
66
|
+
... on VoxelUpdateNotification { mapId chunkX chunkY chunkZ distance decayRate uuid voxelX voxelY voxelZ voxelType voxelState sequenceNumber epochMillis }
|
|
67
|
+
... on GenericErrorResponse { sequenceNumber errorCode }
|
|
68
|
+
... on ActorUpdateResponse { mapId chunkX chunkY chunkZ distance decayRate uuid sequenceNumber epochMillis }
|
|
69
|
+
... on VoxelUpdateResponse { mapId chunkX chunkY chunkZ distance decayRate uuid sequenceNumber epochMillis }
|
|
70
|
+
... on ClientAudioNotification { mapId chunkX chunkY chunkZ distance decayRate uuid audioData sequenceNumber epochMillis }
|
|
71
|
+
... on ClientTextNotification { mapId chunkX chunkY chunkZ distance decayRate uuid text sequenceNumber epochMillis }
|
|
72
|
+
... on ClientEventNotification { mapId chunkX chunkY chunkZ distance decayRate uuid eventType state sequenceNumber epochMillis }
|
|
73
|
+
... on ServerEventNotification { mapId chunkX chunkY chunkZ distance decayRate uuid eventType state sequenceNumber epochMillis }
|
|
140
74
|
}
|
|
141
75
|
}`,
|
|
142
76
|
},
|
|
143
77
|
};
|
|
144
|
-
ws.send(JSON.stringify(
|
|
78
|
+
ws.send(JSON.stringify(subscribeMessage));
|
|
145
79
|
}
|
|
146
|
-
else if (message.type === '
|
|
147
|
-
console.error('Connection error:', message.payload);
|
|
148
|
-
const errorMsg = message.payload?.message || 'Connection rejected - check authorization token';
|
|
149
|
-
console.error('WebSocket connection error:', errorMsg);
|
|
150
|
-
}
|
|
151
|
-
else if (message.type === 'data') {
|
|
80
|
+
else if (message.type === 'next') {
|
|
152
81
|
if (message.payload?.data?.udpNotifications === null) {
|
|
153
82
|
return;
|
|
154
83
|
}
|
|
@@ -168,13 +97,13 @@ export class SubscriptionManager {
|
|
|
168
97
|
}
|
|
169
98
|
}
|
|
170
99
|
else if (message.type === 'error') {
|
|
171
|
-
console.error('
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
100
|
+
console.error('Subscription error:', message.payload);
|
|
101
|
+
}
|
|
102
|
+
else if (message.type === 'complete') {
|
|
103
|
+
// Server ended the subscription
|
|
104
|
+
if (this.wsClient === ws) {
|
|
105
|
+
this.wsClient = null;
|
|
106
|
+
}
|
|
178
107
|
}
|
|
179
108
|
else if (message.type === 'ping') {
|
|
180
109
|
ws.send(JSON.stringify({ type: 'pong' }));
|
|
@@ -200,7 +129,7 @@ export class SubscriptionManager {
|
|
|
200
129
|
if (this.subscriptionId) {
|
|
201
130
|
ws.send(JSON.stringify({
|
|
202
131
|
id: this.subscriptionId,
|
|
203
|
-
type: '
|
|
132
|
+
type: 'complete',
|
|
204
133
|
}));
|
|
205
134
|
}
|
|
206
135
|
ws.close();
|
package/dist/types.d.ts
CHANGED
|
@@ -8,9 +8,9 @@ export interface ChunkCoordinates {
|
|
|
8
8
|
z: BigInt;
|
|
9
9
|
}
|
|
10
10
|
export interface ChunkCoordinatesInput {
|
|
11
|
-
x:
|
|
12
|
-
y:
|
|
13
|
-
z:
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
z: number;
|
|
14
14
|
}
|
|
15
15
|
export interface VoxelCoordinates {
|
|
16
16
|
x: number;
|
|
@@ -76,7 +76,7 @@ export interface UdpProxyConnectionStatus {
|
|
|
76
76
|
lastMessageTime?: string;
|
|
77
77
|
}
|
|
78
78
|
export interface ActorUpdateRequestInput {
|
|
79
|
-
mapId:
|
|
79
|
+
mapId: number;
|
|
80
80
|
chunk: ChunkCoordinatesInput;
|
|
81
81
|
uuid: string;
|
|
82
82
|
state: string;
|
|
@@ -85,7 +85,7 @@ export interface ActorUpdateRequestInput {
|
|
|
85
85
|
sequenceNumber?: number;
|
|
86
86
|
}
|
|
87
87
|
export interface VoxelUpdateRequestInput {
|
|
88
|
-
mapId:
|
|
88
|
+
mapId: number;
|
|
89
89
|
chunk: ChunkCoordinatesInput;
|
|
90
90
|
uuid: string;
|
|
91
91
|
voxel: VoxelCoordinatesInput;
|
|
@@ -96,7 +96,7 @@ export interface VoxelUpdateRequestInput {
|
|
|
96
96
|
sequenceNumber?: number;
|
|
97
97
|
}
|
|
98
98
|
export interface ClientAudioPacketInput {
|
|
99
|
-
mapId:
|
|
99
|
+
mapId: number;
|
|
100
100
|
chunk: ChunkCoordinatesInput;
|
|
101
101
|
uuid: string;
|
|
102
102
|
audioData: string;
|
|
@@ -105,7 +105,7 @@ export interface ClientAudioPacketInput {
|
|
|
105
105
|
sequenceNumber?: number;
|
|
106
106
|
}
|
|
107
107
|
export interface ClientTextPacketInput {
|
|
108
|
-
mapId:
|
|
108
|
+
mapId: number;
|
|
109
109
|
chunk: ChunkCoordinatesInput;
|
|
110
110
|
uuid: string;
|
|
111
111
|
text: string;
|
|
@@ -114,7 +114,7 @@ export interface ClientTextPacketInput {
|
|
|
114
114
|
sequenceNumber?: number;
|
|
115
115
|
}
|
|
116
116
|
export interface ClientEventNotificationInput {
|
|
117
|
-
mapId:
|
|
117
|
+
mapId: number;
|
|
118
118
|
chunk: ChunkCoordinatesInput;
|
|
119
119
|
uuid: string;
|
|
120
120
|
eventType: number;
|
|
@@ -129,8 +129,12 @@ export interface ActorUpdateNotification {
|
|
|
129
129
|
chunkX: BigInt;
|
|
130
130
|
chunkY: BigInt;
|
|
131
131
|
chunkZ: BigInt;
|
|
132
|
+
distance: number;
|
|
133
|
+
decayRate: number;
|
|
132
134
|
uuid: string;
|
|
133
135
|
state: string;
|
|
136
|
+
sequenceNumber: number;
|
|
137
|
+
epochMillis: BigInt;
|
|
134
138
|
}
|
|
135
139
|
export interface ActorUpdateResponse {
|
|
136
140
|
__typename: 'ActorUpdateResponse';
|
|
@@ -138,8 +142,11 @@ export interface ActorUpdateResponse {
|
|
|
138
142
|
chunkX: BigInt;
|
|
139
143
|
chunkY: BigInt;
|
|
140
144
|
chunkZ: BigInt;
|
|
145
|
+
distance: number;
|
|
146
|
+
decayRate: number;
|
|
141
147
|
uuid: string;
|
|
142
148
|
sequenceNumber: number;
|
|
149
|
+
epochMillis: BigInt;
|
|
143
150
|
}
|
|
144
151
|
export interface VoxelUpdateNotification {
|
|
145
152
|
__typename: 'VoxelUpdateNotification';
|
|
@@ -147,12 +154,16 @@ export interface VoxelUpdateNotification {
|
|
|
147
154
|
chunkX: BigInt;
|
|
148
155
|
chunkY: BigInt;
|
|
149
156
|
chunkZ: BigInt;
|
|
157
|
+
distance: number;
|
|
158
|
+
decayRate: number;
|
|
150
159
|
uuid: string;
|
|
151
160
|
voxelX: number;
|
|
152
161
|
voxelY: number;
|
|
153
162
|
voxelZ: number;
|
|
154
163
|
voxelType: number;
|
|
155
164
|
voxelState: string;
|
|
165
|
+
sequenceNumber: number;
|
|
166
|
+
epochMillis: BigInt;
|
|
156
167
|
}
|
|
157
168
|
export interface VoxelUpdateResponse {
|
|
158
169
|
__typename: 'VoxelUpdateResponse';
|
|
@@ -160,8 +171,11 @@ export interface VoxelUpdateResponse {
|
|
|
160
171
|
chunkX: BigInt;
|
|
161
172
|
chunkY: BigInt;
|
|
162
173
|
chunkZ: BigInt;
|
|
174
|
+
distance: number;
|
|
175
|
+
decayRate: number;
|
|
163
176
|
uuid: string;
|
|
164
177
|
sequenceNumber: number;
|
|
178
|
+
epochMillis: BigInt;
|
|
165
179
|
}
|
|
166
180
|
export interface ClientAudioNotification {
|
|
167
181
|
__typename: 'ClientAudioNotification';
|
|
@@ -169,8 +183,12 @@ export interface ClientAudioNotification {
|
|
|
169
183
|
chunkX: BigInt;
|
|
170
184
|
chunkY: BigInt;
|
|
171
185
|
chunkZ: BigInt;
|
|
186
|
+
distance: number;
|
|
187
|
+
decayRate: number;
|
|
172
188
|
uuid: string;
|
|
173
189
|
audioData: string;
|
|
190
|
+
sequenceNumber: number;
|
|
191
|
+
epochMillis: BigInt;
|
|
174
192
|
}
|
|
175
193
|
export interface ClientTextNotification {
|
|
176
194
|
__typename: 'ClientTextNotification';
|
|
@@ -178,8 +196,12 @@ export interface ClientTextNotification {
|
|
|
178
196
|
chunkX: BigInt;
|
|
179
197
|
chunkY: BigInt;
|
|
180
198
|
chunkZ: BigInt;
|
|
199
|
+
distance: number;
|
|
200
|
+
decayRate: number;
|
|
181
201
|
uuid: string;
|
|
182
202
|
text: string;
|
|
203
|
+
sequenceNumber: number;
|
|
204
|
+
epochMillis: BigInt;
|
|
183
205
|
}
|
|
184
206
|
export interface ClientEventNotification {
|
|
185
207
|
__typename: 'ClientEventNotification';
|
|
@@ -187,9 +209,13 @@ export interface ClientEventNotification {
|
|
|
187
209
|
chunkX: BigInt;
|
|
188
210
|
chunkY: BigInt;
|
|
189
211
|
chunkZ: BigInt;
|
|
212
|
+
distance: number;
|
|
213
|
+
decayRate: number;
|
|
190
214
|
uuid: string;
|
|
191
215
|
eventType: number;
|
|
192
216
|
state: string;
|
|
217
|
+
sequenceNumber: number;
|
|
218
|
+
epochMillis: BigInt;
|
|
193
219
|
}
|
|
194
220
|
export interface ServerEventNotification {
|
|
195
221
|
__typename: 'ServerEventNotification';
|
|
@@ -197,9 +223,13 @@ export interface ServerEventNotification {
|
|
|
197
223
|
chunkX: BigInt;
|
|
198
224
|
chunkY: BigInt;
|
|
199
225
|
chunkZ: BigInt;
|
|
226
|
+
distance: number;
|
|
227
|
+
decayRate: number;
|
|
200
228
|
uuid: string;
|
|
201
229
|
eventType: number;
|
|
202
230
|
state: string;
|
|
231
|
+
sequenceNumber: number;
|
|
232
|
+
epochMillis: BigInt;
|
|
203
233
|
}
|
|
204
234
|
export interface GenericErrorResponse {
|
|
205
235
|
__typename: 'GenericErrorResponse';
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|