diff --git a/proto/layer.1.yml b/proto/layer.1.yml new file mode 100644 index 0000000..5b41d7f --- /dev/null +++ b/proto/layer.1.yml @@ -0,0 +1,529 @@ +version: 1 + +enums: + #Type of attachment + AttachmentType: + type: int8 + values: + - id: 0 + name: IMAGE #Image + - id: 1 + name: MESSAGES #Reply/Forwarded messages + - id: 2 + name: FILE #File + - id: 3 + name: AVATAR #Avatar + - id: 4 + name: CALL #Call + - id: 5 + name: VOICE #Voice message + - id: 6 + name: VIDEO_CIRCLE #Video circle + + #Solution by device after accept or decline request to attach new device + DeviceSolution: + type: int8 + values: + - id: 0 + name: ACCEPT #Accept device to log in to account + - id: 1 + name: DECLINE #Decline device + + #Handshake Stage (need for set device confirm view after pass seed) + HandshakeStage: + type: int8 + values: + - id: 0 + name: COMPLETED + - id: 1 + name: NEED_DEVICE_VERIFICATION + + GroupStatus: + type: int8 + values: + - id: 0 + name: JOINED + - id: 1 + name: INVALID + - id: 2 + name: NOT_JOINED + - id: 3 + name: BANNED + + NotificationAction: + type: int8 + values: + - id: 0 + name: SUBSCRIBE + - id: 1 + name: UNSUBSCRIBE + + SignalType: + type: int8 + values: + - id: 0 + name: CALL + - id: 1 + name: KEY_EXCHANGE + - id: 2 + name: ACTIVE_CALL + - id: 3 + name: END_CALL + - id: 4 + name: ACTIVE + - id: 5 + name: END_CALL_BECAUSE_PEER_DISCONNECTED + - id: 6 + name: END_CALL_BECAUSE_BUSY + - id: 7 + name: ACCEPT + - id: 8 + name: RINGING_TIMEOUT + + NetworkStatus: + type: int8 + values: + - id: 0 + name: ONLINE + - id: 1 + name: OFFLINE + + SyncStatus: + type: int8 + values: + - id: 0 + name: NOT_NEEDED + - id: 1 + name: BATCH_START + - id: 2 + name: BATCH_END + + WebRTCType: + type: int8 + values: + - id: 0 + name: OFFER + - id: 1 + name: ANSWER + - id: 2 + name: ICE_CANDIDATE + + ResultCode: + type: int8 + values: + - id: 0 + name: SUCCESS + - id: 1 + name: ERROR + - id: 2 + name: INVALID + - id: 3 + name: USERNAME_TAKEN + + TokenType: + type: int8 + values: + - id: 0 + name: FCM + - id: 1 + name: VoIPApns + +types: + Attachment: + fields: + - id: 1 + name: id + type: string + - id: 2 + name: blob? + type: string + - id: 3 + name: type + type: AttachmentType + - id: 4 + name: preview + type: string + - id: 5 + name: transport + type: AttachmentTransport + + AttachmentTransport: + fields: + - id: 1 + name: transportTag + type: string + - id: 2 + name: transportServer + type: string + + NetworkDevice: + fields: + - id: 1 + name: networkStatus + type: NetworkStatus + - id: 2 + name: deviceName + type: string + - id: 3 + name: deviceOs + type: string + - id: 4 + name: deviceId + type: string + - id: 5 + name: deviceSolution + type: DeviceSolution + + PKNetworkStatus: + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: networkStatus + type: NetworkStatus + + SearchInfo: + fields: + - id: 1 + name: username + type: string + - id: 2 + name: title + type: string + - id: 3 + name: publicKey + type: string + - id: 4 + name: verified + type: int32 + - id: 5 + name: networkStatus + type: NetworkStatus + + RTCIceServer: + fields: + - id: 1 + name: url + type: string + - id: 2 + name: username + type: string + - id: 3 + name: credential + type: string + - id: 4 + name: transport + type: string + +packets: + Handshake: + id: 0 + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: privateKey + type: string + - id: 3 + name: deviceId + type: string + - id: 4 + name: deviceName + type: string + - id: 5 + name: deviceOs + type: string + - id: 6 + name: handshakeStage? + type: HandshakeStage + + UserInfo: + id: 1 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: username + type: string + - id: 3 + name: title + type: string + + Result: + id: 2 + fields: + - id: 1 + name: resultCode + type: ResultCode + + Search: + id: 3 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: search + type: string + - id: 3 + name: searchInfo? + type: SearchInfo[] + + OnlineSubscribe: + id: 4 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: publicKeys + type: string[] + + OnlineState: + id: 5 + fields: + - id: 1 + name: pkNetworkStatuses + type: PKNetworkStatus[] + + Message: + id: 6 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + - id: 4 + name: content + type: string + - id: 5 + name: chachaKey + type: string + - id: 6 + name: timestamp + type: int64 + - id: 7 + name: messageId + type: string + - id: 8 + name: attachments? + type: Attachment[] + - id: 9 + name: aesChachaKey + type: string + + Read: + id: 7 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + + Delivery: + id: 8 + fields: + - id: 1 + name: messageId + type: string + - id: 2 + name: toPublicKey + type: string + + DeviceNew: + id: 9 + fields: + - id: 1 + name: ipAddress + type: string + - id: 2 + name: deviceId + type: string + - id: 3 + name: deviceName + type: string + - id: 4 + name: deviceOs + type: string + + RequestUpdate: + id: 10 + fields: + - id: 1 + name: server? + type: string + + Typeing: + id: 11 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + + RequestTransport: + id: 15 + fields: + - id: 1 + name: server? + type: string + + PushNotification: + id: 16 + fields: + - id: 1 + name: notificationToken + type: string + - id: 2 + name: action + type: NotificationAction + - id: 3 + name: tokenType + type: TokenType + - id: 4 + name: deviceId + type: string + + GroupCreate: + id: 17 + fields: + - id: 1 + name: groupId + type: string + + GroupInfo: + id: 18 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersPKs? + type: string[] + + GroupInviteInfo: + id: 19 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersCount? + type: int32 + - id: 3 + name: status? + type: GroupStatus + + GroupJoin: + id: 20 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: status? + type: GroupStatus + - id: 3 + name: groupString + type: string + + GroupLeave: + id: 21 + fields: + - id: 1 + name: groupId + type: string + + GroupBan: + id: 22 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: publicKey + type: string + + DeviceList: + id: 23 + fields: + - id: 1 + name: devices + type: NetworkDevice[] + + DeviceResolve: + id: 24 + fields: + - id: 1 + name: deviceId + type: string + - id: 2 + name: solution + type: DeviceSolution + + Sync: + id: 25 + fields: + - id: 1 + name: syncStatus + type: SyncStatus + - id: 2 + name: timestamp + type: int64 + + SignalPeer: + id: 26 + fields: + - id: 1 + name: src + type: string + - id: 2 + name: dst + type: string + - id: 3 + name: sharedPublic + type: string + - id: 4 + name: signalType + type: SignalType + - id: 5 + name: callId + type: string + - id: 6 + name: joinToken + type: string + + WebRTC: + id: 27 + fields: + - id: 1 + name: sdpOrCandidate + type: string + - id: 2 + name: type + type: WebRTCType + + IceServers: + id: 28 + fields: + - id: 1 + name: iceServers? + type: RTCIceServer[] \ No newline at end of file diff --git a/proto/layer.2.yml b/proto/layer.2.yml new file mode 100644 index 0000000..f599583 --- /dev/null +++ b/proto/layer.2.yml @@ -0,0 +1,527 @@ +version: 2 +description: Remove avatars as attachments, add video + +enums: + AttachmentType: + type: int8 + values: + - id: 0 + name: IMAGE + - id: 1 + name: MESSAGES + - id: 2 + name: FILE + - id: 4 + name: CALL + - id: 5 + name: VOICE + - id: 6 + name: VIDEO_CIRCLE + - id: 7 + name: VIDEO + + DeviceSolution: + type: int8 + values: + - id: 0 + name: ACCEPT + - id: 1 + name: DECLINE + + HandshakeStage: + type: int8 + values: + - id: 0 + name: COMPLETED + - id: 1 + name: NEED_DEVICE_VERIFICATION + + GroupStatus: + type: int8 + values: + - id: 0 + name: JOINED + - id: 1 + name: INVALID + - id: 2 + name: NOT_JOINED + - id: 3 + name: BANNED + + NotificationAction: + type: int8 + values: + - id: 0 + name: SUBSCRIBE + - id: 1 + name: UNSUBSCRIBE + + SignalType: + type: int8 + values: + - id: 0 + name: CALL + - id: 1 + name: KEY_EXCHANGE + - id: 2 + name: ACTIVE_CALL + - id: 3 + name: END_CALL + - id: 4 + name: ACTIVE + - id: 5 + name: END_CALL_BECAUSE_PEER_DISCONNECTED + - id: 6 + name: END_CALL_BECAUSE_BUSY + - id: 7 + name: ACCEPT + - id: 8 + name: RINGING_TIMEOUT + + NetworkStatus: + type: int8 + values: + - id: 0 + name: ONLINE + - id: 1 + name: OFFLINE + + SyncStatus: + type: int8 + values: + - id: 0 + name: NOT_NEEDED + - id: 1 + name: BATCH_START + - id: 2 + name: BATCH_END + + WebRTCType: + type: int8 + values: + - id: 0 + name: OFFER + - id: 1 + name: ANSWER + - id: 2 + name: ICE_CANDIDATE + + ResultCode: + type: int8 + values: + - id: 0 + name: SUCCESS + - id: 1 + name: ERROR + - id: 2 + name: INVALID + - id: 3 + name: USERNAME_TAKEN + + TokenType: + type: int8 + values: + - id: 0 + name: FCM + - id: 1 + name: VoIPApns + +types: + Attachment: + fields: + - id: 1 + name: id + type: string + - id: 2 + name: blob? + type: string + - id: 3 + name: type + type: AttachmentType + - id: 4 + name: preview + type: string + - id: 5 + name: transport + type: AttachmentTransport + + AttachmentTransport: + fields: + - id: 1 + name: transportTag + type: string + - id: 2 + name: transportServer + type: string + + NetworkDevice: + fields: + - id: 1 + name: networkStatus + type: NetworkStatus + - id: 2 + name: deviceName + type: string + - id: 3 + name: deviceOs + type: string + - id: 4 + name: deviceId + type: string + - id: 5 + name: deviceSolution + type: DeviceSolution + + PKNetworkStatus: + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: networkStatus + type: NetworkStatus + + SearchInfo: + fields: + - id: 1 + name: username + type: string + - id: 2 + name: title + type: string + - id: 3 + name: publicKey + type: string + - id: 4 + name: verified + type: int32 + - id: 5 + name: networkStatus + type: NetworkStatus + + RTCIceServer: + fields: + - id: 1 + name: url + type: string + - id: 2 + name: username + type: string + - id: 3 + name: credential + type: string + - id: 4 + name: transport + type: string + +packets: + Handshake: + id: 0 + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: privateKey + type: string + - id: 3 + name: deviceId + type: string + - id: 4 + name: deviceName + type: string + - id: 5 + name: deviceOs + type: string + - id: 6 + name: handshakeStage? + type: HandshakeStage + + UserInfo: + id: 1 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: username + type: string + - id: 3 + name: title + type: string + + Result: + id: 2 + fields: + - id: 1 + name: resultCode + type: ResultCode + + Search: + id: 3 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: search + type: string + - id: 3 + name: searchInfo? + type: SearchInfo[] + + OnlineSubscribe: + id: 4 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: publicKeys + type: string[] + + OnlineState: + id: 5 + fields: + - id: 1 + name: pkNetworkStatuses + type: PKNetworkStatus[] + + Message: + id: 6 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + - id: 4 + name: content + type: string + - id: 5 + name: chachaKey + type: string + - id: 6 + name: timestamp + type: int64 + - id: 7 + name: messageId + type: string + - id: 8 + name: attachments? + type: Attachment[] + - id: 9 + name: aesChachaKey + type: string + + Read: + id: 7 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 4 + name: timestamp + type: int64 + + Delivery: + id: 8 + fields: + - id: 1 + name: messageId + type: string + - id: 2 + name: toPublicKey + type: string + + DeviceNew: + id: 9 + fields: + - id: 1 + name: ipAddress + type: string + - id: 2 + name: deviceId + type: string + - id: 3 + name: deviceName + type: string + - id: 4 + name: deviceOs + type: string + + RequestUpdate: + id: 10 + fields: + - id: 1 + name: server? + type: string + + Typeing: + id: 11 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + + RequestTransport: + id: 15 + fields: + - id: 1 + name: server? + type: string + + PushNotification: + id: 16 + fields: + - id: 1 + name: notificationToken + type: string + - id: 2 + name: action + type: NotificationAction + - id: 3 + name: tokenType + type: TokenType + - id: 4 + name: deviceId + type: string + + GroupCreate: + id: 17 + fields: + - id: 1 + name: groupId? + type: string + + GroupInfo: + id: 18 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersPKs? + type: string[] + + GroupInviteInfo: + id: 19 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersCount? + type: int32 + - id: 3 + name: status? + type: GroupStatus + + GroupJoin: + id: 20 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: status? + type: GroupStatus + - id: 3 + name: groupString + type: string + + GroupLeave: + id: 21 + fields: + - id: 1 + name: groupId + type: string + + GroupBan: + id: 22 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: publicKey + type: string + + DeviceList: + id: 23 + fields: + - id: 1 + name: devices + type: NetworkDevice[] + + DeviceResolve: + id: 24 + fields: + - id: 1 + name: deviceId + type: string + - id: 2 + name: solution + type: DeviceSolution + + Sync: + id: 25 + fields: + - id: 1 + name: syncStatus + type: SyncStatus + - id: 2 + name: timestamp + type: int64 + + SignalPeer: + id: 26 + fields: + - id: 1 + name: src + type: string + - id: 2 + name: dst + type: string + - id: 3 + name: sharedPublic? + type: string + - id: 4 + name: signalType + type: SignalType + - id: 5 + name: callId? + type: string + - id: 6 + name: joinToken? + type: string + + WebRTC: + id: 27 + fields: + - id: 1 + name: sdpOrCandidate + type: string + - id: 2 + name: type + type: WebRTCType + + IceServers: + id: 28 + fields: + - id: 1 + name: iceServers? + type: RTCIceServer[] \ No newline at end of file diff --git a/proto/layer.3.yml b/proto/layer.3.yml new file mode 100644 index 0000000..20f586a --- /dev/null +++ b/proto/layer.3.yml @@ -0,0 +1,651 @@ +version: 3 +description: Add avatars and more CDN safety, remove transport server + +enums: + AttachmentType: + type: int8 + values: + - id: 0 + name: IMAGE + - id: 1 + name: MESSAGES + - id: 2 + name: FILE + - id: 4 + name: CALL + - id: 5 + name: VOICE + - id: 6 + name: VIDEO_CIRCLE + - id: 7 + name: VIDEO + + DeviceSolution: + type: int8 + values: + - id: 0 + name: ACCEPT + - id: 1 + name: DECLINE + + HandshakeStage: + type: int8 + values: + - id: 0 + name: COMPLETED + - id: 1 + name: NEED_DEVICE_VERIFICATION + + GroupStatus: + type: int8 + values: + - id: 0 + name: JOINED + - id: 1 + name: INVALID + - id: 2 + name: NOT_JOINED + - id: 3 + name: BANNED + + NotificationAction: + type: int8 + values: + - id: 0 + name: SUBSCRIBE + - id: 1 + name: UNSUBSCRIBE + + SignalType: + type: int8 + values: + - id: 0 + name: CALL + - id: 1 + name: KEY_EXCHANGE + - id: 2 + name: ACTIVE_CALL + - id: 3 + name: END_CALL + - id: 4 + name: ACTIVE + - id: 5 + name: END_CALL_BECAUSE_PEER_DISCONNECTED + - id: 6 + name: END_CALL_BECAUSE_BUSY + - id: 7 + name: ACCEPT + - id: 8 + name: RINGING_TIMEOUT + + NetworkStatus: + type: int8 + values: + - id: 0 + name: ONLINE + - id: 1 + name: OFFLINE + + SyncStatus: + type: int8 + values: + - id: 0 + name: NOT_NEEDED + - id: 1 + name: BATCH_START + - id: 2 + name: BATCH_END + + WebRTCType: + type: int8 + values: + - id: 0 + name: OFFER + - id: 1 + name: ANSWER + - id: 2 + name: ICE_CANDIDATE + + ResultCode: + type: int8 + values: + - id: 0 + name: SUCCESS + - id: 1 + name: ERROR + - id: 2 + name: INVALID #любая ошибка смысл которой зависит от контекста, например в случае с файловой системой - нет файла + - id: 3 + name: USERNAME_TAKEN + - id: 4 + name: OVERSIZE #слишком большой размер файла + - id: 5 + name: OVERLIFE #слишком большой TTL + + TokenType: + type: int8 + values: + - id: 0 + name: FCM + - id: 1 + name: VoIPApns + + #Тип медиа файла профиля (пока только фото) + ProfileMediaType: + type: uint8 + values: + - id: 0 + name: PROFILE_PHOTO + +types: + Attachment: + fields: + - id: 1 + name: id + type: string + - id: 2 + name: blob? + type: string + - id: 3 + name: type + type: AttachmentType + - id: 4 + name: preview + type: string + - id: 6 + name: objectId + type: string + + #Медиа-файлы профиля такие как аватарки (фото) и будущие истории + ProfileMedia: + fields: + - id: 1 + name: preview #превью (для фото blurhash) + type: string + - id: 2 + name: objectId #обьект на cdn + type: string + - id: 3 + name: type #тип медиа + type: ProfileMediaType + - id: 4 + name: timestamp #дата публикации + type: int64 + - id: 5 + name: mediaKey #ключ шифрования от медиа + type: string + + NetworkDevice: + fields: + - id: 1 + name: networkStatus + type: NetworkStatus + - id: 2 + name: deviceName + type: string + - id: 3 + name: deviceOs + type: string + - id: 4 + name: deviceId + type: string + - id: 5 + name: deviceSolution + type: DeviceSolution + + PKNetworkStatus: + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: networkStatus + type: NetworkStatus + + #Информация при поиске пользователя (приходит в ответ на пакет PacketSearch) + SearchInfo: + fields: + - id: 1 + name: username #имя для поиска + type: string + - id: 2 + name: title #отображаемое имя пользователя + type: string + - id: 3 + name: publicKey #публичный ключ + type: string + - id: 4 + name: verified #верификация + type: int32 + - id: 5 + name: networkStatus #онлайн пользователь или нет + type: NetworkStatus + - id: 6 + name: avatar? #аватар пользователя если есть + type: ProfileMedia + + #Информация которая используется только при входе в профиль пользователя + ProfileInfo: + fields: + - id: 1 + name: username #имя для поиска + type: string + - id: 2 + name: title #отображаемое имя пользователя + type: string + - id: 3 + name: publicKey #публичный ключ + type: string + - id: 4 + name: verified #верификация + type: int32 + - id: 5 + name: networkStatus #онлайн пользователь или нет + type: NetworkStatus + - id: 6 + name: media? #все активное медиа (включая будущие истории) + type: ProfileMedia[] + + RTCIceServer: + fields: + - id: 1 + name: url + type: string + - id: 2 + name: username + type: string + - id: 3 + name: credential + type: string + - id: 4 + name: transport + type: string + +packets: + Handshake: + id: 0 + fields: + - id: 1 + name: publicKey + type: string + - id: 2 + name: privateKey + type: string + - id: 3 + name: deviceId + type: string + - id: 4 + name: deviceName + type: string + - id: 5 + name: deviceOs + type: string + - id: 6 + name: handshakeStage? + type: HandshakeStage + + UserInfo: + id: 1 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: username + type: string + - id: 3 + name: title + type: string + + Result: + id: 2 + fields: + - id: 1 + name: resultCode + type: ResultCode + + Search: + id: 3 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: search + type: string + - id: 3 + name: searchInfo? + type: SearchInfo[] + + OnlineSubscribe: + id: 4 + fields: + - id: 1 + name: privateKey + type: string + - id: 2 + name: publicKeys + type: string[] + + OnlineState: + id: 5 + fields: + - id: 1 + name: pkNetworkStatuses + type: PKNetworkStatus[] + + Message: + id: 6 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + - id: 4 + name: content + type: string + - id: 5 + name: chachaKey + type: string + - id: 6 + name: timestamp + type: int64 + - id: 7 + name: messageId + type: string + - id: 8 + name: attachments? + type: Attachment[] + - id: 9 + name: aesChachaKey + type: string + + Read: + id: 7 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 4 + name: timestamp + type: int64 + + Delivery: + id: 8 + fields: + - id: 1 + name: messageId + type: string + - id: 2 + name: toPublicKey + type: string + + DeviceNew: + id: 9 + fields: + - id: 1 + name: ipAddress + type: string + - id: 2 + name: deviceId + type: string + - id: 3 + name: deviceName + type: string + - id: 4 + name: deviceOs + type: string + + RequestUpdate: + id: 10 + fields: + - id: 1 + name: server? + type: string + + Typeing: + id: 11 + fields: + - id: 1 + name: fromPublicKey + type: string + - id: 2 + name: toPublicKey + type: string + - id: 3 + name: privateKey + type: string + + #Запрос транспортного сервера + RequestTransport: + id: 15 + fields: + - id: 1 #сервер > клиент + name: server? #выбранный транспортный сервер + type: string + + PushNotification: + id: 16 + fields: + - id: 1 + name: notificationToken + type: string + - id: 2 + name: action + type: NotificationAction + - id: 3 + name: tokenType + type: TokenType + - id: 4 + name: deviceId + type: string + + GroupCreate: + id: 17 + fields: + - id: 1 + name: groupId? + type: string + + GroupInfo: + id: 18 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersPKs? + type: string[] + + GroupInviteInfo: + id: 19 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: membersCount? + type: int32 + - id: 3 + name: status? + type: GroupStatus + + GroupJoin: + id: 20 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: status? + type: GroupStatus + - id: 3 + name: groupString + type: string + + GroupLeave: + id: 21 + fields: + - id: 1 + name: groupId + type: string + + GroupBan: + id: 22 + fields: + - id: 1 + name: groupId + type: string + - id: 2 + name: publicKey + type: string + + DeviceList: + id: 23 + fields: + - id: 1 + name: devices + type: NetworkDevice[] + + DeviceResolve: + id: 24 + fields: + - id: 1 + name: deviceId + type: string + - id: 2 + name: solution + type: DeviceSolution + + Sync: + id: 25 + fields: + - id: 1 + name: syncStatus + type: SyncStatus + - id: 2 + name: timestamp + type: int64 + + SignalPeer: + id: 26 + fields: + - id: 1 + name: src + type: string + - id: 2 + name: dst + type: string + - id: 3 + name: sharedPublic? + type: string + - id: 4 + name: signalType + type: SignalType + - id: 5 + name: callId? + type: string + - id: 6 + name: joinToken? + type: string + + WebRTC: + id: 27 + fields: + - id: 1 + name: sdpOrCandidate + type: string + - id: 2 + name: type + type: WebRTCType + + IceServers: + id: 28 + fields: + - id: 1 + name: iceServers? + type: RTCIceServer[] + + #Запрос "посадочного места" у сервера при загрузке файла + UploadCandidate: + id: 29 + fields: + - id: 1 #клиент > сервер + name: size #размер загружаемого файла (декларируемый) + type: uint32 + - id: 2 #сервер > клиент + name: objectId? #выделенный сервером objectId + type: string + - id: 3 #сервер > клиент + name: chunkLength? #размер чанка + type: uint32 + - id: 4 #сервер > клиент + name: chunks? #количество чанков + type: uint32 + - id: 5 #сервер > клиент + name: host? #хост, где сохранен файл + type: string + - id: 6 #клиент > сервер + name: ttl? #ttl в секундах, после которого файл будет удален с CDN и с таблицы, по умолчанию 7 дней, не допускается использование слишком больших значений + type: uint32 + + #Запрос скачивания файла с сервера, нужно передать objectId, а дальнейшую информацию вернет сервер + DownloadCandidate: + id: 30 + fields: + - id: 1 #сервер > клиент + name: size? #размер файла + type: uint32 + - id: 2 #клиент > сервер + name: objectId #выделенный сервером objectId + type: string + - id: 3 #сервер > клиент + name: chunkLength? #размер чанка + type: uint32 + - id: 4 #сервер > клиент + name: chunks? #количество чанков + type: uint32 + - id: 5 #сервер > клиент + name: host? #сервер с которого скачивать файл + type: string + + #Установить аватар профиля + SetAvatar: + id: 31 + fields: + - id: 1 #клиент > сервер + name: objectId #выделенный сервером objectId при отправке пакета UploadCandidate + type: string + - id: 2 #клиент > сервер + name: blurhash #превью аватара, строка blurhash + type: string + - id: 3 #клиент > сервер + name: mediaKey #ключ шифрования + type: string + + #Удаляет аватар или фотографию из профиля + RemoveAvatar: + id: 32 + fields: + - id: 1 #клиент > сервер + name: objectId #objectId аватара, аватар или фотография профиля должна при этом стоять у профиля отправителя пакета + type: string + + #Запрос профиля + Profile: + id: 33 + fields: + - id: 1 #клиент > сервер + name: publicKey + type: string + - id: 2 #сервер > клиент + name: info? + type: ProfileInfo \ No newline at end of file diff --git a/scripts/generate-proto-docs.mjs b/scripts/generate-proto-docs.mjs index 664bdba..e0b2716 100644 --- a/scripts/generate-proto-docs.mjs +++ b/scripts/generate-proto-docs.mjs @@ -5,7 +5,7 @@ import { isMap, isSeq, parseDocument, stringify } from 'yaml'; const projectRoot = resolve(fileURLToPath(new URL('..', import.meta.url))); const sourceDirectory = resolve( - process.env.ROSETTA_PROTO_DIR || resolve(projectRoot, '../rcc/proto'), + process.env.ROSETTA_PROTO_DIR || resolve(projectRoot, 'proto'), ); const outputPath = resolve(projectRoot, 'src/generated/protoDocs.ts'); @@ -139,7 +139,7 @@ async function readLayer(path) { let sourceFiles = []; try { sourceFiles = (await readdir(sourceDirectory)) - .filter((file) => /\.ya?ml$/i.test(file)) + .filter((file) => /^layer\..+\.ya?ml$/i.test(file)) .sort((a, b) => a.localeCompare(b, undefined, { numeric: true })) .map((file) => resolve(sourceDirectory, file)); } catch { diff --git a/src/pages/ProtoPage.module.css b/src/pages/ProtoPage.module.css index 746d2ee..ffb6c0c 100644 --- a/src/pages/ProtoPage.module.css +++ b/src/pages/ProtoPage.module.css @@ -16,6 +16,22 @@ border: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-5)); } +.protoSubheading { + margin: 30px 0 12px; + color: light-dark(var(--mantine-color-dark-8), var(--mantine-color-dark-0)); + font-size: 17px; + font-weight: 650; +} + +.layerExamples { + margin: 18px 0 24px; +} + +.layerExamples .protoCode { + height: calc(100% - 30px); + margin-bottom: 0; +} + .docsLink { display: inline-block; margin-top: 44px; diff --git a/src/pages/ProtoPage.tsx b/src/pages/ProtoPage.tsx index 67c05c6..afa462a 100644 --- a/src/pages/ProtoPage.tsx +++ b/src/pages/ProtoPage.tsx @@ -374,13 +374,147 @@ field_id:uint8 | wire_type:uint8 | [length:uint16] | value - + - Protocol layers are generated from RCC YAML schemas. Every layer defines - packet IDs, field IDs, primitive types, reusable types, enumerations, and - optional values. Keeping field IDs stable allows compatible decoders to - read known fields while the schema evolves. + Each layer.N.yml file is a complete protocol snapshot. Its + top-level version is the layer number. RCC sorts all layers by + that number, rejects duplicate versions, and builds a timeline for every + packet, field, type, and enum value. A newer layer repeats the definitions + that still exist and adds, removes, or makes fields optional as needed. + + Packet IDs should remain stable, and RCC explicitly validates field-ID + reuse inside every packet and type. An existing field ID cannot be assigned + to a different field name or type in a later layer. A new field receives a + new ID; an optional field may be omitted by older peers. The server + generator keeps version-aware codecs for the supported range, while a + client generator produces the current layer. + + + RCC does not negotiate a layer over the network by itself. The connection + or handshake code selects a version supported by both peers, then passes + that number to the generated server codec. The registry exposes the + minimum and maximum compiled versions, and the codec includes only fields + whose lifetime contains the selected version. TLV fields that are not used + by that layer do not become properties of the decoded packet. + + + + Two simple layers + + + + Layer 1 + + {`version: 1 + +packets: + Profile: + id: 10 + fields: + - id: 1 + name: username + type: string`} + + + + Layer 2 + + {`version: 2 + +packets: + Profile: + id: 10 + fields: + - id: 1 + name: username + type: string + - id: 2 + name: displayName? + type: string`} + + + + + Layer 2 preserves packet ID 10 and field ID + 1, then introduces optional field ID 2. A layer 1 + peer sends and reads only username. A layer 2 peer can include + displayName, but does not require it. + + + + Simplified server output + + + In server mode RCC combines both snapshots into one model and a codec that + receives the negotiated version. The generated source is more verbose; the + following excerpt keeps only the versioning decisions. + + + {`public class PacketProfile extends Packet { + public String username; + public String displayName; // introduced in layer 2 +} + +public class PacketProfileCodec { + private static final int F_USERNAME = 1; + private static final int F_DISPLAY_NAME = 2; + + public PacketProfile decode(ByteBuf data, int version) { + TlvReader reader = new TlvReader(data); + PacketProfile packet = new PacketProfile(); + packet.username = requireField(reader.getString(F_USERNAME)); + + if (version >= 2) { + packet.displayName = reader.getString(F_DISPLAY_NAME); + } + return packet; + } + + public ByteBuf encode(PacketProfile packet, int version) { + TlvWriter writer = new TlvWriter(); + writer.writeString(F_USERNAME, packet.username); + + if (version >= 2 && packet.displayName != null) { + writer.writeString(F_DISPLAY_NAME, packet.displayName); + } + return writer.getBuffer(); + } +}`} + + + RCC also writes the supported interval to the generated registry. A packet + codec can reject a layer older than the packet's introduction. Removed + fields remain available to the server model and codec only for the layers + in which they existed; enum values receive equivalent + isSupportedInVersion checks. + + + {`public final class RccGeneratedPacketRegistry { + public static final int MIN_VERSION = 1; + public static final int MAX_VERSION = 2; + public static final int PACKET_PROFILE_ID = 10; +}`} + + + + Latest client output + + + A TypeScript client is generated from the latest layer, so application code + sees the current shape and the optional marker directly. + + + {`export class PacketProfile extends Packet { + username!: string; + displayName?: string; +} + +export class RccGeneratedPacketRegistry { + static readonly VERSION = 2; + static readonly PACKET_PROFILE_ID = 10; +}`} + @@ -707,10 +841,11 @@ export function ProtoDocsPage() { setSearch(event.currentTarget.value)} leftSection={} - placeholder="Search packets, types, fields, or enums" + placeholder="Packets, types, fields, or enums" aria-label="Search Proto documentation" /> diff --git a/src/pages/SupportPage.module.css b/src/pages/SupportPage.module.css index f8e0dc2..a7ac30c 100644 --- a/src/pages/SupportPage.module.css +++ b/src/pages/SupportPage.module.css @@ -40,12 +40,12 @@ } .searchInput input { - height: 64px; - padding-inline: 58px; - border-color: transparent; + height: 56px; + padding-inline: 50px; + border-color: light-dark(var(--mantine-color-gray-4), var(--mantine-color-dark-4)); background: light-dark(var(--mantine-color-white), var(--mantine-color-dark-7)); - box-shadow: 0 12px 38px rgba(25, 113, 194, 0.16); - font-size: 17px; + box-shadow: none; + font-size: 16px; } .searchInput input:focus { diff --git a/src/pages/SupportPage.tsx b/src/pages/SupportPage.tsx index 61ba0b8..deccf35 100644 --- a/src/pages/SupportPage.tsx +++ b/src/pages/SupportPage.tsx @@ -108,9 +108,6 @@ export function SupportPage() { - - Rosetta Support - How can we help? Search account access, messaging, media, privacy, and security help. @@ -135,8 +132,8 @@ export function SupportPage() { } placeholder="Describe your problem" aria-label="Search Rosetta support" - size="xl" - radius="xl" + size="lg" + radius="sm" className={classes.searchInput} />