udp-node-msgs.proto 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. syntax = "proto2";
  2. import "profile.proto"; //enums PlayerType and Sport
  3. import "per-session-info.proto"; //TcpConfig
  4. enum ZofflineConstants {
  5. RealmID = 1; // hardcoded in ZwiftApp=1 (g_CurrentServerRealmID, 0: never connected; -1: disconnected)
  6. }
  7. enum WA_TYPE {
  8. WAT_LEAVE = 2; //proto::PlayerLeftWorld
  9. WAT_RELOGIN = 3; //proto::PlayerLeftWorld
  10. WAT_RIDE_ON = 4; //proto::RideOn
  11. WAT_SPA = 5; //proto::SocialPlayerAction (chat message)
  12. WAT_EVENT = 6; //proto::Event
  13. WAT_JOIN_E = 7; //proto::PlayerJoinedEvent
  14. WAT_LEFT_E = 8; //proto::PlayerLeftEvent
  15. WAT_RQ_PROF = 9; //proto::RequestProfileFromServer
  16. WAT_INV_W = 10; //proto::ReceiveInvitationWorldAttribute
  17. WAT_KICKED = 11; //no payload
  18. WAT_WTIME = 100; //g_WorldTime := payload (GOD message, may be ignored if ZWIFT\CONFIG\IGNOREGODMESSAGES=1)
  19. WAT_RTIME = 101; //BlimpEntity::SetRoadTime(payload), also GOD message
  20. WAT_B_ACT = 102; //BikeEntity::PerformAction(payload)
  21. WAT_GRP_M = 103; //GroupMessage (may be ignored if ZWIFT\CONFIG\SHOWGROUPMSGS=1)
  22. WAT_PRI_M = 104; //PrivateMessage
  23. WAT_SR = 105; //proto::SegmentResult
  24. WAT_FLAG = 106; //Leaderboards::FlagSandbagger / Leaderboards::FlagCheater
  25. WAT_NONE = 107; //does nothing
  26. WAT_RLA = 108; //ZNETWORK_BroadcastRideLeaderAction
  27. WAT_GE = 109; //GroupEvents::UserSignedup / GroupEvents::UserRegistered
  28. WAT_NM = 110; //notable moment + Play_Magic_Whoosh_Deep_Sparkle
  29. WAT_LATE = 111; //ZNETWORK_INTERNAL_HandleLateJoinRequest
  30. WAT_RH = 112; //ZNETWORK_INTERNAL_HandleRouteHashRequest
  31. WAT_STATS = 113; //GLOBAL_MESSAGE_TYPE_RIDER_FENCE_STATS
  32. WAT_FENCE = 114; //GLOBAL_MESSAGE_TYPE_GRFENCE_CONFIG
  33. WAT_BN_GE = 115; //ZNETWORK_BroadcastBibNumberForGroupEvent
  34. WAT_PPI = 116; //ZNETWORK_INTERNAL_HandlePacePartnerInfo
  35. }
  36. enum UserBikeAction {
  37. UBA_ELBOW = 0;
  38. UBA_WAVE = 1;
  39. UBA_02 = 2; //BikeEntity::UpdateAnimation
  40. UBA_RIDEON = 3;
  41. UBA_HAMMER = 4;
  42. UBA_NICE = 5;
  43. UBA_BRING_IT = 6;
  44. UBA_TOAST = 7;
  45. UBA_BELL = 8;
  46. UBA_HOLIDAY_WAVE = 9; //not sure
  47. }
  48. message WorldAttribute {
  49. optional int64 wa_f1 = 1; //not r/w by game? 587645624533328784, later 5876456 85771834256
  50. optional int64 server_realm = 2;
  51. optional WA_TYPE wa_type = 3;
  52. optional bytes payload = 4; //not only protobuf
  53. optional int64 world_time_born = 5;
  54. optional int64 x = 6; //stored as int32
  55. optional int64 y_altitude = 7; //stored as int32
  56. optional int64 z = 8; //stored as int32
  57. optional int64 world_time_expire = 9;
  58. optional int64 rel_id = 10; //WAT_PPI: pace partner smth; WAT_SPA: to_player_id; WAT_RH: route_id? ...
  59. optional int32 importance = 11; //not read by game??? WAT_B_ACT:1000; WAT_NM:50000; WAT_RH:5000000; ... 75000 ?
  60. optional int64 wa_f12 = 12; //not r/w by game? Not in package when testing
  61. optional int32 wa_f13 = 13; //not r/w by game?
  62. optional int64 timestamp = 14; //not written by game? (from server) looks like "The Current Epoch Unix Timestamp" in Microseconds
  63. optional int32 wa_f15 = 15; //6, not r/w by game?
  64. optional int64 wa_f16 = 16; //not r/w by game? stored as bool
  65. }
  66. message PlayerLeftWorld {
  67. required int64 player_id = 1;
  68. optional int64 world_time = 2; // not sure
  69. optional bool anotherLogin = 3; // user profile logged in twice -> one of them should be logged out
  70. optional bool plw_f4 = 4; //true
  71. repeated sint64 plw_f5 = 5; // [1056322864]
  72. }
  73. /*message WorldAttributes {
  74. repeated WorldAttribute world_attributes = 1;
  75. required int64 world_time = 2;
  76. }
  77. message World { //zwift.protobuf.World
  78. required uint64 id = 1;
  79. required string name = 2;
  80. required uint64 w_f3 = 3;
  81. optional bool w_f4 = 4;
  82. required uint64 w_f5 = 5;
  83. required uint64 world_time = 6;
  84. required uint64 real_time = 7;
  85. repeated Player w_f8 = 8;
  86. }
  87. message Player {
  88. optional PlayerProfile player_profile = 1;
  89. optional PlayerState player_state = 2;
  90. }*/
  91. enum POWERUP_TYPE {
  92. LIGHTNESS = 0;
  93. DRAFTBOOST = 1;
  94. BONUS_XP_LIGHT = 2;
  95. BONUS_XP = 3;
  96. UNDRAFTABLE = 4;
  97. AERO = 5;
  98. NINJA = 6;
  99. STEAMROLLER = 7;
  100. ANVIL = 8;
  101. POWERUP_CNT = 9;
  102. POWERUP_NONE = 15;
  103. }
  104. message PlayerState {
  105. optional int64 id = 1;
  106. optional int64 worldTime = 2; // milliseconds
  107. optional int32 distance = 3; // meters
  108. optional int32 roadTime = 4; // 1/100 sec
  109. optional int32 laps = 5;
  110. optional uint32 speed = 6; // millimeters per hour
  111. optional uint32 ps_f7 = 7;
  112. optional int32 roadPosition = 8;
  113. optional int32 cadenceUHz = 9; // =(cad / 60) * 1000000
  114. optional int32 ps_f10 = 10; // BikeEntity.field_B58; 0 - ETA related (something around speed)
  115. optional int32 heartrate = 11;
  116. optional int32 power = 12;
  117. optional int64 heading = 13;
  118. optional int64 lean = 14;
  119. optional int32 climbing = 15; // meters
  120. optional int32 time = 16; // seconds
  121. optional int32 ps_f17 = 17;
  122. optional uint32 frameHue = 18; // BikeEntity::DrawBike m_frameHue * 255.0
  123. //field 19:
  124. //byte[0].bits[0,1]: HasPowerMeter, HasPhoneConnected
  125. //byte[0].bits[2,3]: RoadDirectionForward, ??? !BikeEntity.field_DCC || BikeEntity.disSteer
  126. //byte[0].bits[4]: read in BikeEntity::ProcessNewPacket, steering-related
  127. //byte[1]: =0 ???
  128. //byte[2]: fallback course/getMapRevisionId
  129. //byte[3]: realRideons (not counted yet in BikeEntity::m_rideons) @ BikeEntity::UpdateRideOns, see also BikeEntity::Update
  130. optional uint32 f19 = 19;
  131. //ZNETWORK_SerializeAux3: low 4 bits=POWERUP_TYPE; next 4 bits: BikeEntity.field_2B14+1; next 8 bits: road_id
  132. // BikeEntity.field_2b16: true-> |= 0x2000000, false-> |= 0x1000000 (bits 24-25)
  133. // bit 28: EbikeBoost::GetActiveBoostOption
  134. optional uint32 aux3 = 20;
  135. optional uint32 progress = 21; // WorkoutMode = progress & 0xF, up to 7 including (workoutPhaseType+1 or 0)
  136. optional int64 customizationId = 22;
  137. optional bool justWatching = 23;
  138. optional int32 calories = 24;
  139. optional float x = 25;
  140. optional float y_altitude = 26;
  141. optional float z = 27;
  142. optional int64 watchingRiderId = 28;
  143. optional int64 groupId = 29;
  144. // 30 absent at least in Android Game
  145. optional Sport sport = 31;
  146. optional float ps_f32 = 32;
  147. optional uint32 ps_f33 = 33;
  148. optional float dist_lat = 34; //= BikeEntity.field_F00 (=219.56387 and incr if moving: actual distance moved included lateral movement)
  149. optional int32 world = 35;
  150. optional uint32 ps_f36 = 36; // = f(BikeEntity.field_2a28) BikeEntity::CreateNewPacket
  151. optional uint32 ps_f37 = 37; // = f(BikeEntity.field_2a28) BikeEntity::CreateNewPacket
  152. optional bool canSteer = 38; // = BikeEntity.m_canSteer
  153. optional int32 route = 39;
  154. }
  155. message ClientToServer {
  156. required int64 server_realm = 1; //UdpClient::sendDisconnectedClientToServer: -1. Otherwise g_CurrentServerRealmID (RealmID or 0 if not connected yet)
  157. required int64 player_id = 2;
  158. optional int64 world_time = 3;
  159. optional uint32 seqno = 4;
  160. optional uint32 cts_f5 = 5;
  161. optional int64 cts_f6 = 6;
  162. required PlayerState state = 7;
  163. optional bool cts_f8 = 8;
  164. optional bool cts_f9 = 9;
  165. required int64 last_update = 10;
  166. optional bool cts_f11 = 11;
  167. required int64 last_player_update = 12;
  168. optional int64 larg_wa_time = 13; //TcpClient::sayHello: LargestWorldAttributeTimestamp
  169. optional bool cts_f14 = 14;
  170. repeated int64 subsSegments = 15; //subscribed segment ids? TcpClient::sayHello, TcpClient::sendSubscribeToSegment
  171. repeated int64 unsSegments = 16; //unsubscribed segment ids? TcpClient::processSegmentUnsubscription
  172. }
  173. message PlayerSummary {
  174. optional int32 plsu_f1 = 1;
  175. optional int32 plsu_f2 = 2;
  176. optional int32 plsu_f3 = 3;
  177. optional int32 plsu_f4 = 4;
  178. }
  179. message PlayerSummaries {
  180. optional sint64 plsus_f1 = 1; //stored as int32
  181. optional sint64 plsus_f2 = 2; //stored as int32
  182. optional sint32 plsus_f3 = 3;
  183. optional sint32 plsus_f4 = 4;
  184. optional int32 plsus_f5 = 5;
  185. optional int32 plsus_f6 = 6;
  186. optional int32 plsus_f7 = 7;
  187. repeated PlayerSummary player_summaries = 8;
  188. }
  189. message RelayAddress {
  190. optional int32 lb_realm = 1; // load balancing cluster: server realm or 0 (generic)
  191. optional int32 lb_course = 2; // load balancing cluster: course id
  192. optional string ip = 3;
  193. optional int32 port = 4;
  194. optional float ra_f5 = 5; //used when appropriate server selection occurs (RelayAddressService::getAddress)
  195. optional float ra_f6 = 6; //used when appropriate server selection occurs (RelayAddressService::getAddress)
  196. }
  197. message UdpConfig {
  198. repeated RelayAddress relay_addresses = 1;
  199. optional int32 uc_f2 = 2; //=10?
  200. optional int32 uc_f3 = 3; //=30?
  201. optional int32 uc_f4 = 4; //=3?
  202. }
  203. message RelayAddressesVOD {
  204. optional int32 lb_realm = 1; // load balancing cluster: server realm or 0 (generic)
  205. optional int32 lb_course = 2; // load balancing cluster: course id
  206. repeated RelayAddress relay_addresses = 3;
  207. optional bool rav_f4 = 4; //server selection method: true->higher (ra_f5, ra_f6), false->nearest (ra_f5, ra_f6)
  208. }
  209. message UdpConfigVOD {
  210. repeated RelayAddressesVOD relay_addresses_vod = 1;
  211. optional int32 port = 2;
  212. optional int64 ucv_f3 = 3;
  213. optional int64 ucv_f4 = 4;
  214. optional float ucv_f5 = 5;
  215. optional float ucv_f6 = 6;
  216. }
  217. message PlayerRouteDistance {
  218. optional int32 player_id = 1; //BikeManager::FindBikeWithNetworkID
  219. optional float distance_covered = 2; //not sure
  220. optional int32 millisec_to_leader = 3; // ZNETWORK_INTERNAL_ProcessPlayerPackets
  221. }
  222. message EventSubgroupPlacements {
  223. optional int32 position = 1; //UdpStatistics::registerFanViewLatestPlayerStateInfo
  224. repeated PlayerRouteDistance player_rd1 = 2;
  225. repeated PlayerRouteDistance player_rd2 = 3;
  226. repeated PlayerRouteDistance eventRiderPosition = 4;
  227. repeated PlayerRouteDistance player_rd4 = 5;
  228. optional int32 eventTotalRiders = 6;
  229. optional int32 bikeNetworkId = 7;
  230. optional int32 millisec_to_leader = 8; //ZNETWORK_INTERNAL_ProcessPlayerPackets
  231. optional float esp_f9 = 9; //or fixed
  232. }
  233. enum IPProtocol {
  234. UDP = 1;
  235. TCP = 2;
  236. }
  237. enum ExpungeReason {
  238. NOT_EXPUNGED = 0;
  239. WORLD_FULL = 1;
  240. ROADS_CLOSED = 2;
  241. }
  242. message ServerToClient {
  243. optional int64 server_realm = 1;
  244. optional int64 player_id = 2;
  245. optional int64 world_time = 3;
  246. optional int32 seqno = 4;
  247. optional int32 stc_f5 = 5; //low-priority world time sync algo (not investigated yet, maybe deprecated) in WorldClockService::calculateOneLegLatency
  248. // 6,7: absent
  249. repeated PlayerState states = 8;
  250. repeated WorldAttribute updates = 9;
  251. repeated int64 stc_f10 = 10;
  252. optional bool stc_f11 = 11; //=true???
  253. optional string zc_local_ip = 12;
  254. optional int64 stc_f13 = 13;
  255. optional int32 zwifters = 14;
  256. optional int32 zc_local_port = 15;
  257. optional IPProtocol zc_protocol = 16;
  258. optional int64 cts_latency = 17; //high-priority world time sync algo in WorldClockService::calculateOneLegLatency
  259. optional int32 num_msgs = 18;
  260. optional int32 msgnum = 19;
  261. optional bool hasSimultLogin = 20; //UdpClient::disconnectionRequested due to simultaneous login (1); OR simultaneous login ceased (0)
  262. optional PlayerSummaries player_summaries = 21; //tag426
  263. // 22 absent
  264. optional EventSubgroupPlacements ev_subgroup_ps = 23; //tag442
  265. optional UdpConfig udp_config = 24; //tag450
  266. optional UdpConfigVOD udp_config_vod_1 = 25; //tag458
  267. optional ExpungeReason expungeReason = 26; //tag464 UdpClient::receivedExpungeReason
  268. optional UdpConfigVOD udp_config_vod_2 = 27; //tag474
  269. repeated PlayerState player_states = 28; //tag482
  270. optional TcpConfig tcp_config = 29; //tag490
  271. repeated int64 ackSubsSegm = 30; //tag496 TcpClient::processSubscribedSegment
  272. optional uint32 stc_f31 = 31; //tag508
  273. optional bytes zc_key = 32; //tag642
  274. }
  275. message Ghost { //not from the Zwift game, zoffline-specific!
  276. required int32 player_id = 1;
  277. repeated PlayerState states = 2;
  278. }
  279. message RideOn {
  280. required int64 player_id = 1;
  281. required int64 to_player_id = 2;
  282. required string firstName = 3;
  283. required string lastName = 4;
  284. required int32 countryCode = 5;
  285. }