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