Новый лендинг

This commit is contained in:
2026-07-31 06:06:07 -07:00
parent 8b2af4db62
commit 871c84cedd
8 changed files with 1873 additions and 18 deletions

529
proto/layer.1.yml Normal file
View File

@@ -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[]

527
proto/layer.2.yml Normal file
View File

@@ -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[]

651
proto/layer.3.yml Normal file
View File

@@ -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

View File

@@ -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 {

View File

@@ -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;

View File

@@ -374,13 +374,147 @@ field_id:uint8 | wire_type:uint8 | [length:uint16] | value
</LegalList>
</LegalSection>
<LegalSection title="Layers and compatibility">
<LegalSection title="Protocol versioning">
<LegalText>
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 <Code>layer.N.yml</Code> file is a complete protocol snapshot. Its
top-level <Code>version</Code> 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.
</LegalText>
<LegalText>
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.
</LegalText>
<LegalText>
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.
</LegalText>
<Title order={3} className={classes.protoSubheading}>
Two simple layers
</Title>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="md" className={classes.layerExamples}>
<Box>
<Text fw={650} size="sm">Layer 1</Text>
<Code block className={classes.protoCode}>
{`version: 1
packets:
Profile:
id: 10
fields:
- id: 1
name: username
type: string`}
</Code>
</Box>
<Box>
<Text fw={650} size="sm">Layer 2</Text>
<Code block className={classes.protoCode}>
{`version: 2
packets:
Profile:
id: 10
fields:
- id: 1
name: username
type: string
- id: 2
name: displayName?
type: string`}
</Code>
</Box>
</SimpleGrid>
<LegalText>
Layer 2 preserves packet ID <Code>10</Code> and field ID
<Code> 1</Code>, then introduces optional field ID <Code>2</Code>. A layer 1
peer sends and reads only <Code>username</Code>. A layer 2 peer can include
<Code> displayName</Code>, but does not require it.
</LegalText>
<Title order={3} className={classes.protoSubheading}>
Simplified server output
</Title>
<LegalText>
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.
</LegalText>
<Code block className={classes.protoCode}>
{`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();
}
}`}
</Code>
<LegalText>
RCC also writes the supported interval to the generated registry. A packet
codec can reject a layer older than the packet&apos;s introduction. Removed
fields remain available to the server model and codec only for the layers
in which they existed; enum values receive equivalent
<Code> isSupportedInVersion</Code> checks.
</LegalText>
<Code block className={classes.protoCode}>
{`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;
}`}
</Code>
<Title order={3} className={classes.protoSubheading}>
Latest client output
</Title>
<LegalText>
A TypeScript client is generated from the latest layer, so application code
sees the current shape and the optional marker directly.
</LegalText>
<Code block className={classes.protoCode}>
{`export class PacketProfile extends Packet {
username!: string;
displayName?: string;
}
export class RccGeneratedPacketRegistry {
static readonly VERSION = 2;
static readonly PACKET_PROFILE_ID = 10;
}`}
</Code>
</LegalSection>
<LegalSection title="How an RCC YAML layer is structured">
@@ -707,10 +841,11 @@ export function ProtoDocsPage() {
<Box className={classes.documentation}>
<Box className={classes.filters}>
<TextInput
label="Search"
value={search}
onChange={(event) => setSearch(event.currentTarget.value)}
leftSection={<IconSearch size={17} />}
placeholder="Search packets, types, fields, or enums"
placeholder="Packets, types, fields, or enums"
aria-label="Search Proto documentation"
/>
<Text c="dimmed" size="xs">

View File

@@ -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 {

View File

@@ -108,9 +108,6 @@ export function SupportPage() {
</ThemeIcon>
<Stack align="center" gap="sm" className={classes.heroContent}>
<Text fw={700} size="sm" c="blue.8">
Rosetta Support
</Text>
<Title order={1}>How can we help?</Title>
<Text c="blue.9" ta="center" className={classes.heroDescription}>
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}
/>