-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathchanneld.proto
511 lines (408 loc) · 19.8 KB
/
channeld.proto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
syntax = "proto3";
package channeldpb;
import "google/protobuf/any.proto";
option go_package = "github.com/channeldorg/channeld/pkg/channeldpb";
// The data packet that is sent between the endpoints. A packet can have multiple messages in the payload in one trip to improve the efficiency.
message Packet {
repeated MessagePack messages = 1;
}
// The serialized message and the context of it.
message MessagePack {
// The ID of the channel that the message is sent to, or received from channeld.
// 0 is the GLOBAL channel; 1-65535 are for non-spatial channels;
// beyond (0xffff-0xffffffff) are reserved for spatial channels.
uint32 channelId = 1;
// How the message will be broadcasted to all connections in the channel?
// See @BroadcastType. ONLY works for the user-space messages.
uint32 broadcast = 2;
// The stub for RPC callbacks.
// 0 means the message is not a RPC message.
uint32 stubId = 3;
// The MessageType either defined in @MessageType enum, or defined in user space.
uint32 msgType = 4;
// The serialized message. It's Protobuf-marshalled byte array if the message is defined in @MessageType.
bytes msgBody = 5;
}
/*
Connection Type | Broadcast_NO | Broadacst_ALL | Broadcast_SINGLE_CONNECTION
------------------------------------------------------------------------------------------------------------------------
Client | forward to owner | broadcast if no owner && enableClientBroadcast | same as Broadacst_ALL
Server | forward to owner | broadcast (same for ALL_BUT_XXXX) | forward to client connection
*/
// Can be used as the Flags-style enum in C#. See https://groups.google.com/g/protobuf/c/L105Q4NIk0U?pli=1.
enum BroadcastType {
// No broadcast. All internal messages should use this type, and other types are ignored.
NO_BROADCAST = 0;
// Forward the message to the connection. Can only be used by the backend server.
// This has the same behavior as sending the message to the PRIVATE channel owned by the target connection with BroadcastType = NO.
SINGLE_CONNECTION = 1;
// Broadcast the message to all the connections in the channel, the sender included.
ALL = 2;
// Broadcast the message to all the connections in the channel, the sender excluded.
ALL_BUT_SENDER = 4;
// Broadcast the message to all the connections in the channel, the owner excluded.
ALL_BUT_OWNER = 8;
// Broadcast the message to all client connections in the channel.
ALL_BUT_CLIENT = 16;
// Broadcast the message to all server connections in the channel, the owner excluded.
ALL_BUT_SERVER = 32;
// Broadcast the message to all the connections in all the adjacent(3x3) spatial channels. Ignored if the target channel is not a spatial channel.
// To ignore the center spatial channel, use ADJACENT_CHANNELS | ALL_BUT_OWNER; to ignore the sender(spatial server), use ADJACENT_CHANNELS | ALL_BUT_SENDER.
ADJACENT_CHANNELS = 64;
}
enum ConnectionType {
NO_CONNECTION = 0;
SERVER = 1;
CLIENT = 2;
}
enum ChannelType {
UNKNOWN = 0;
// Default channel. Any message without ChannelId specified (equals 0) will be sent to this channel.
GLOBAL = 1;
// Per-connection channel. Useful to store the user data and subscribe the client to the data update.
PRIVATE = 2;
// A game "room" in a session-based game, or a "dungeon" in an MMORPG. Subworlds are spatially divided thus the interests are isolated.
SUBWORLD = 3;
// Spatial channels are spatailly connected. Using this type of channel to implement a seamless open world which consists of servers, and each server simulates a part of the world.
// Only server connections can create the spatial channel.
SPATIAL = 4;
ENTITY = 5;
// The following are for tests.
TEST = 100;
TEST1 = 101;
TEST2 = 102;
TEST3 = 103;
TEST4 = 104;
}
enum MessageType {
INVALID = 0;
// Used by both @AuthMessage and @AuthResultMessage
AUTH = 1;
// Used by both @CreateChannelMessage and @CreateChannelResultMessage
CREATE_CHANNEL = 3;
// Used by @RemoveChannelMessage
REMOVE_CHANNEL = 4;
// Used by both @ListChannelMessage and @ListChannelResultMessage
LIST_CHANNEL = 5;
// Used by both @SubscribedToChannelMessage and @SubscribedToChannelResultMessage
SUB_TO_CHANNEL = 6;
// Used by both @UnsubscribedFromChannelMessage and @UnsubscribedFromChannelResultMessage
UNSUB_FROM_CHANNEL = 7;
// Used by @ChannelDataUpdateMessage
CHANNEL_DATA_UPDATE = 8;
// Used by @DisconnectMessage
DISCONNECT = 9;
// Used by both @CreateChannelMessage and @CreateSpatialChannelsResultMessage
CREATE_SPATIAL_CHANNEL = 10;
// Used by both @QuerySpatialChannelMessage and @QuerySpatialChannelResultMessage
QUERY_SPATIAL_CHANNEL = 11;
// Used by @ChannelDataHandoverMessage
CHANNEL_DATA_HANDOVER = 12;
// Used by @SpatialRegionsUpdateMessage
SPATIAL_REGIONS_UPDATE = 13;
// Used by @UpdateSpatialInterestMessage
UPDATE_SPATIAL_INTEREST = 14;
// Used by @CreateEntityChannelMessage
CREATE_ENTITY_CHANNEL = 15;
// Used by @AddEntityGroupMessage
ENTITY_GROUP_ADD = 16;
// Used by @RemoveEntityGroupMessage
ENTITY_GROUP_REMOVE = 17;
// Used by @SpatialChannelsReadyMessage
SPATIAL_CHANNELS_READY = 18;
// // Used by @StartRecoveryMesssage
// RECOVERY_START = 19;
RECOVERY_CHANNEL_DATA = 20;
// Used by @EndRecoveryMesssage
RECOVERY_END = 21;
// Used by @ChannelOwnerLostMessage
CHANNEL_OWNER_LOST = 22;
// Used by @ChannelOwnerRecoveredMessage
CHANNEL_OWNER_RECOVERED = 23;
// Used by @DebugGetSpatialRegionsMessage
DEBUG_GET_SPATIAL_REGIONS = 99;
// Start of any user-space defined message
USER_SPACE_START = 100;
}
// The message that is used to carries user-space message and communicate between channeld and backend servers.
// Users don't need to use this message directly if they are using a client library.
message ServerForwardMessage {
// The client that sends the user-space message to server or server sends the user-space message to.
// If a server sends to channeld with clientConnId = 0, the message will be forwarded to the channel owner.
uint32 clientConnId = 1;
// The user-space message. channeld leaves it as the original binary format.
bytes payload = 2;
}
// The message should have channelId = 0 in order to be handled.
// Response: @AuthResultMessage. The GLOBAL channel owner will also receive this message (to handle the client's subscription if it doesn't have the authority to).
message AuthMessage {
string playerIdentifierToken = 1;
string loginToken = 2;
}
enum CompressionType {
NO_COMPRESSION = 0;
// https://github.com/google/snappy
SNAPPY = 1;
}
message AuthResultMessage {
enum AuthResult {
SUCCESSFUL = 0;
INVALID_PIT = 1;
INVALID_LT = 2;
}
AuthResult result = 1;
uint32 connId = 2;
// The compression type should be used for future communication.
// However, because the compression type is specified per packet, the client has its freedom to control which compression type to use.
// It's useful when the client has too much CPU load for the compression, or the network debug is needed.
CompressionType compressionType = 3;
bool shouldRecover = 4;
}
enum ChannelDataAccess {
NO_ACCESS = 0;
READ_ACCESS = 1;
WRITE_ACCESS = 2;
}
message ChannelSubscriptionOptions {
// Should the subscriber be able to update the channel data?
// Use enum over bool as in Protobuf, after setting a bool field to true, merging it with false won't work!
optional ChannelDataAccess dataAccess = 1;
// How the fields are filtered before sending to the subscriber.
// For detailed usage, see https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask.
repeated string dataFieldMasks = 2;
// How frequent the updated channel data will be fanned-out to the subscriber, in millisecond.
// For an MMORPG-style server/client, the value should be between 50-100, while an FPS-style game, the value should be between 10-30.
optional uint32 fanOutIntervalMs = 3;
// How long between the subscription and the first (and full-state) ChannelDataUpdateMessage being send to the subscriber, in millisecond.
// To be accurate, the first fan-out time will be (sub time + fan-out delay). It's possible to set the delay to a negative value to makee the first fan-out happen earlier.
// Fan-out delay is useful when the clients need spawn message (sent from the backend server) to be handled, before handling the ChannelDataUpdateMessage properly.
// In Mirror, it can take up to 100ms to wait.
optional int32 fanOutDelayMs = 4;
// Whether the subscriber should skip the fan-out of its own ChannelDataUpdate. Default is true.
optional bool skipSelfUpdateFanOut = 5;
// Whether the subscriber should skip the first fan-out that contains the full states. Default is false.
optional bool skipFirstFanOut = 6;
}
// Defines how two @ChannelDataUpdateMessage.data are merged.
// The custom merge function should always be implemented for the sake of performance. Otherwise,
// the default merge that based on Protobuf's reflection will be used, and it's >10 times slower.
message ChannelDataMergeOptions {
// By default, Protobuf appends the src list to the dst list. Setting this option to true will replace the dst list with the src list.
bool shouldReplaceList = 1;
// If the value is greater than 0, truncate the the list when oversized.
uint32 listSizeLimit = 2;
// If true, the top elements of the list will be truncated instead of the end. It's useful for scenarios like chat message list.
bool truncateTop = 3;
// If true, the merge method will remove any map entry that has removed=true in its value.
bool shouldCheckRemovableMapField = 4;
}
// The message should have channelId = 0 in order to be handled.
// Response: @CreateChannelResultMessage, if the MessageType is CREATE_CHANNEL and the channelType is not SPATIAL. The GLOBAL channel owner will also receive this message.
// Response: @CreateSpatialChannelsResultMessage, if the MessageType is CREATE_SPATIAL_CHANNEL and the channelType is SPATIAL. The GLOBAL channel owner will also receive this message.
// Response: @SubscribedToChannelResultMessage. The channel creator will also be subscribed to the channel immediately after the creation.
message CreateChannelMessage {
ChannelType channelType = 1;
string metadata = 2;
ChannelSubscriptionOptions subOptions = 3;
google.protobuf.Any data = 4;
ChannelDataMergeOptions mergeOptions = 5;
}
message CreateChannelResultMessage {
ChannelType channelType = 1;
string metadata = 2;
uint32 ownerConnId = 3;
// The ID of the newly-created channel. Add this field to differentiate it from MessagePack.channelId.
uint32 channelId = 4;
}
// The message should have channelId = 0 in order to be handled.
// Response: all connections in the channel will receive @RemoveChannelMessage. The GLOBAL channel owner will also receive this message.
message RemoveChannelMessage {
uint32 channelId = 1;
}
// The message should have channelId = 0 in order to be handled.
// Response: @ListChannelResultMessage
message ListChannelMessage {
ChannelType typeFilter = 1;
repeated string metadataFilters = 2;
}
message ListChannelResultMessage {
message ChannelInfo {
uint32 channelId = 1;
ChannelType channelType = 2;
string metadata = 3;
}
repeated ChannelInfo channels = 1;
}
// Response: @SubscribedToChannelResultMessage. The message sender, the subscribed connection (if not the sender), and the channel owner will receive the message respectively.
// If the connection has already been subscripbed to the channel, the subOptions will be merged, but no response message will be sent.
message SubscribedToChannelMessage {
// The connection to be added to the channel is not necessarily the one sends the message.
// Remarks: only the channel owner or the GLOBAL channel owner can sub another connection to the channel.
uint32 connId = 1;
ChannelSubscriptionOptions subOptions = 2;
}
message SubscribedToChannelResultMessage {
// The connection that subscribed.
uint32 connId = 1;
ChannelSubscriptionOptions subOptions = 2;
ConnectionType connType = 3;
ChannelType channelType = 4;
}
// Response: @UnsubscribedFromChannelResultMessage. The message sender, the connection that unsubscribed, and the channel owner will receive the message respectively.
message UnsubscribedFromChannelMessage {
// The connection to be removed from the channel is not necessarily the one sends the message.
// Remarks: only the channel owner or the GLOBAL channel can unsub another connection from the channel.
uint32 connId = 1;
}
message UnsubscribedFromChannelResultMessage {
// The connection that unsubsribed.
uint32 connId = 1;
ConnectionType connType = 2;
ChannelType channelType = 3;
}
// Response: no. Each connection in the channel receives the @ChannelDataUpdateMessage in every @ChannelSubscriptionOptions.FanOutIntervalMs
message ChannelDataUpdateMessage {
google.protobuf.Any data = 1;
// The ID of the connection that causes the update of the channel data.
// In a server-authoratative system (which means the @ChannelDataUpdateMessage will only be sent by server), the servers need to send this field to channeld.
// If the sender is a client, this field will be ignored.
uint32 contextConnId = 2;
}
// Disconnect another connection from channeld.
// This message should only be sent by the server connection in a server-authoratative environment.
// The message should have channelId = 0 in order to be handled.
// Response: no.
message DisconnectMessage {
uint32 connId = 1;
}
// message StartRecoveryMesssage {
// }
// A combination of channel sub/create/update messages that are sent from channeld to the connection during the recovery process.
message ChannelDataRecoveryMessage {
uint32 channelId = 1;
ChannelType channelType = 2;
string metadata = 3;
uint32 ownerConnId = 4;
// Used to restore the channel data in order. The connection that recovers should consume the recovery message in the order of subTime.
int64 subTime = 5;
ChannelSubscriptionOptions subOptions = 6;
// Full channel data. Objects should be able to re-created from the states in it.
google.protobuf.Any channelData = 7;
// Additional data that are required to recover the connection, e.g. the spawned objects.
optional google.protobuf.Any recoveryData = 8;
}
message EndRecoveryMesssage {
}
// Sent from channeld to the subscribed connections of a channel when the owner of the channel is lost.
// The client app should decide for itself which functionalities to disable until the owner is recovered.
message ChannelOwnerLostMessage {
}
// Sent from channeld to the subscribed connections of a channel when the owner of the channel is recovered.
// The client app should re-enable the functionalities that are disabled when the owner is lost.
message ChannelOwnerRecoveredMessage {
}
// ----------------- SPATIAL messages start --------------------//
// Left-handed coordinate system with Y-up rule.
message SpatialInfo {
double x = 1;
double y = 2;
double z = 3;
}
message CreateSpatialChannelsResultMessage {
repeated uint32 spatialChannelId = 1;
string metadata = 2;
uint32 ownerConnId = 3;
}
// The message should have channelId = 0 in order to be handled.
// Response: @QuerySpatialChannelResultMessage
message QuerySpatialChannelMessage {
repeated SpatialInfo spatialInfo = 1;
}
message QuerySpatialChannelResultMessage {
repeated uint32 channelId = 1;
}
// Indicates that all the spatial channels are created by the spatial servers, so the servers can continue further initialization.
message SpatialChannelsReadyMessage {
uint32 serverIndex = 1;
uint32 serverCount = 2;
}
// ALL connections in the source AND destination channels receive this messge when a handover happpned.
// Handover means an object moves from a spatial channel to another. It doesn't necessarily mean the objece moves from a spatial server to another.
message ChannelDataHandoverMessage {
uint32 srcChannelId = 1;
uint32 dstChannelId = 2;
// The ID of the client connection that triggered the handover. If the handover is triggered by server (e.g. NPC movement), the value will be 0.
uint32 contextConnId = 3;
// The data that migrate from the source channel to the destination channel. It can be the spatial channel data or anything, as long as the spatial servers can use it to process the handover.
google.protobuf.Any data = 4;
}
message SpatialRegion {
SpatialInfo min = 1;
SpatialInfo max = 2;
uint32 channelId = 3;
uint32 serverIndex = 4;
}
// channeld updates the information of spatial channels and regions to the spatial servers.
// Spatial servers use this information mainly for mapping the position of a spawned object to a correct channelId at realtime (rather than querying it before sending the spawn message to the client).
// Sent upon the creation of spatial channels (after @CreateSpatialChannelsResultMessage being sent), or any regional change (basiclally caused by the loadbalancer).
message SpatialRegionsUpdateMessage {
repeated SpatialRegion regions = 1;
}
message SpatialInterestQuery {
message SpotsAOI {
repeated SpatialInfo spots = 1;
// The fixed distance between each spot and the player. If not specified, 0 = nearest will be used.
repeated uint32 dists = 2;
}
optional SpotsAOI spotsAOI = 1;
message BoxAOI {
SpatialInfo center = 1;
SpatialInfo extent = 2;
}
optional BoxAOI boxAOI = 2;
message SphereAOI {
SpatialInfo center = 1;
double radius = 2;
}
optional SphereAOI sphereAOI = 3;
message ConeAOI {
SpatialInfo center = 1;
SpatialInfo direction = 2;
// In radians.
double angle = 3;
double radius = 4;
}
optional ConeAOI coneAOI = 4;
}
message UpdateSpatialInterestMessage {
uint32 connId = 1;
SpatialInterestQuery query = 2;
}
message CreateEntityChannelMessage {
uint32 entityId = 1;
string metadata = 2;
ChannelSubscriptionOptions subOptions = 3;
google.protobuf.Any data = 4;
ChannelDataMergeOptions mergeOptions = 5;
bool isWellKnown = 6;
}
enum EntityGroupType {
HANDOVER = 0;
LOCK = 1;
}
// Add specified entities to the handover/lock group of the entity channel. Should sent by the entity channel owner.
message AddEntityGroupMessage {
EntityGroupType type = 1;
repeated uint32 EntitiesToAdd = 2;
}
// Remove specified entities from the handover/lock group of the entity channel. Should sent by the entity channel owner.
message RemoveEntityGroupMessage {
EntityGroupType type = 1;
repeated uint32 EntitiesToRemove = 2;
}
// ------------------ DEBUG messages start ---------------------//
// Client requests the spatail regions information. Only valid in Development mode (with "-dev" launch argument).
// Response: @SpatialRegionsUpdateMessage
message DebugGetSpatialRegionsMessage {
}
// ----------------- INTERNAL messages start --------------------//