123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- syntax = "proto2";
- import "profile.proto"; //enums PlayerType and Sport
- import "per-session-info.proto"; //TcpConfig
- enum ZofflineConstants {
- RealmID = 1; // hardcoded in ZwiftApp=1 (g_CurrentServerRealmID, 0: never connected; -1: disconnected)
- }
- enum WA_TYPE {
- WAT_LEAVE = 2; //proto::PlayerLeftWorld
- WAT_RELOGIN = 3; //proto::PlayerLeftWorld
- WAT_RIDE_ON = 4; //proto::RideOn
- WAT_SPA = 5; //proto::SocialPlayerAction (chat message)
- WAT_EVENT = 6; //proto::Event
- WAT_JOIN_E = 7; //proto::PlayerJoinedEvent
- WAT_LEFT_E = 8; //proto::PlayerLeftEvent
- WAT_RQ_PROF = 9; //proto::RequestProfileFromServer
- WAT_INV_W = 10; //proto::ReceiveInvitationWorldAttribute
- WAT_KICKED = 11; //no payload
- WAT_WTIME = 100; //g_WorldTime := payload (GOD message, may be ignored if ZWIFT\CONFIG\IGNOREGODMESSAGES=1)
- WAT_RTIME = 101; //BlimpEntity::SetRoadTime(payload), also GOD message
- WAT_B_ACT = 102; //BikeEntity::PerformAction(payload)
- WAT_GRP_M = 103; //GroupMessage (may be ignored if ZWIFT\CONFIG\SHOWGROUPMSGS=1)
- WAT_PRI_M = 104; //PrivateMessage
- WAT_SR = 105; //proto::SegmentResult
- WAT_FLAG = 106; //Leaderboards::FlagSandbagger / Leaderboards::FlagCheater
- WAT_NONE = 107; //does nothing
- WAT_RLA = 108; //ZNETWORK_BroadcastRideLeaderAction
- WAT_GE = 109; //GroupEvents::UserSignedup / GroupEvents::UserRegistered
- WAT_NM = 110; //notable moment + Play_Magic_Whoosh_Deep_Sparkle
- WAT_LATE = 111; //ZNETWORK_INTERNAL_HandleLateJoinRequest
- WAT_RH = 112; //ZNETWORK_INTERNAL_HandleRouteHashRequest
- WAT_STATS = 113; //GLOBAL_MESSAGE_TYPE_RIDER_FENCE_STATS
- WAT_FENCE = 114; //GLOBAL_MESSAGE_TYPE_GRFENCE_CONFIG
- WAT_BN_GE = 115; //ZNETWORK_BroadcastBibNumberForGroupEvent
- WAT_PPI = 116; //ZNETWORK_INTERNAL_HandlePacePartnerInfo
- }
- enum UserBikeAction {
- UBA_ELBOW = 0;
- UBA_WAVE = 1;
- UBA_02 = 2; //BikeEntity::UpdateAnimation
- UBA_RIDEON = 3;
- UBA_HAMMER = 4;
- UBA_NICE = 5;
- UBA_BRING_IT = 6;
- UBA_TOAST = 7;
- UBA_BELL = 8;
- UBA_HOLIDAY_WAVE = 9; //not sure
- }
- message WorldAttribute {
- optional int64 wa_f1 = 1; //not r/w by game? 587645624533328784, later 5876456 85771834256
- optional int64 server_realm = 2;
- optional WA_TYPE wa_type = 3;
- optional bytes payload = 4; //not only protobuf
- optional int64 world_time_born = 5;
- optional int64 x = 6; //stored as int32
- optional int64 y_altitude = 7; //stored as int32
- optional int64 z = 8; //stored as int32
- optional int64 world_time_expire = 9;
- optional int64 rel_id = 10; //WAT_PPI: pace partner smth; WAT_SPA: to_player_id; WAT_RH: route_id? ...
- optional int32 importance = 11; //not read by game??? WAT_B_ACT:1000; WAT_NM:50000; WAT_RH:5000000; ... 75000 ?
- optional int64 wa_f12 = 12; //not r/w by game? Not in package when testing
- optional int32 wa_f13 = 13; //not r/w by game?
- optional int64 timestamp = 14; //not written by game? (from server) looks like "The Current Epoch Unix Timestamp" in Microseconds
- optional int32 wa_f15 = 15; //6, not r/w by game?
- optional int64 wa_f16 = 16; //not r/w by game? stored as bool
- }
- message PlayerLeftWorld {
- required int64 player_id = 1;
- optional int64 world_time = 2; // not sure
- optional bool anotherLogin = 3; // user profile logged in twice -> one of them should be logged out
- optional bool plw_f4 = 4; //true
- repeated sint64 plw_f5 = 5; // [1056322864]
- }
- /*message WorldAttributes {
- repeated WorldAttribute world_attributes = 1;
- required int64 world_time = 2;
- }
- message World { //zwift.protobuf.World
- required uint64 id = 1;
- required string name = 2;
- required uint64 w_f3 = 3;
- optional bool w_f4 = 4;
- required uint64 w_f5 = 5;
- required uint64 world_time = 6;
- required uint64 real_time = 7;
- repeated Player w_f8 = 8;
- }
- message Player {
- optional PlayerProfile player_profile = 1;
- optional PlayerState player_state = 2;
- }*/
- enum POWERUP_TYPE {
- LIGHTNESS = 0;
- DRAFTBOOST = 1;
- BONUS_XP_LIGHT = 2;
- BONUS_XP = 3;
- UNDRAFTABLE = 4;
- AERO = 5;
- NINJA = 6;
- STEAMROLLER = 7;
- ANVIL = 8;
- POWERUP_CNT = 9;
- POWERUP_NONE = 15;
- }
- message PlayerState {
- optional int64 id = 1;
- optional int64 worldTime = 2; // milliseconds
- optional int32 distance = 3; // meters
- optional int32 roadTime = 4; // 1/100 sec
- optional int32 laps = 5;
- optional uint32 speed = 6; // millimeters per hour
- optional uint32 ps_f7 = 7;
- optional int32 roadPosition = 8;
- optional int32 cadenceUHz = 9; // =(cad / 60) * 1000000
- optional int32 ps_f10 = 10; // BikeEntity.field_B58; 0 - ETA related (something around speed)
- optional int32 heartrate = 11;
- optional int32 power = 12;
- optional int64 heading = 13;
- optional int64 lean = 14;
- optional int32 climbing = 15; // meters
- optional int32 time = 16; // seconds
- optional int32 ps_f17 = 17;
- optional uint32 frameHue = 18; // BikeEntity::DrawBike m_frameHue * 255.0
- //field 19:
- //byte[0].bits[0,1]: HasPowerMeter, HasPhoneConnected
- //byte[0].bits[2,3]: RoadDirectionForward, ??? !BikeEntity.field_DCC || BikeEntity.disSteer
- //byte[0].bits[4]: read in BikeEntity::ProcessNewPacket, steering-related
- //byte[1]: =0 ???
- //byte[2]: fallback course/getMapRevisionId
- //byte[3]: realRideons (not counted yet in BikeEntity::m_rideons) @ BikeEntity::UpdateRideOns, see also BikeEntity::Update
- optional uint32 f19 = 19;
- //ZNETWORK_SerializeAux3: low 4 bits=POWERUP_TYPE; next 4 bits: BikeEntity.field_2B14+1; next 8 bits: road_id
- // BikeEntity.field_2b16: true-> |= 0x2000000, false-> |= 0x1000000 (bits 24-25)
- // bit 28: EbikeBoost::GetActiveBoostOption
- optional uint32 aux3 = 20;
- optional uint32 progress = 21; // WorkoutMode = progress & 0xF, up to 7 including (workoutPhaseType+1 or 0)
- optional int64 customizationId = 22;
- optional bool justWatching = 23;
- optional int32 calories = 24;
- optional float x = 25;
- optional float y_altitude = 26;
- optional float z = 27;
- optional int64 watchingRiderId = 28;
- optional int64 groupId = 29;
- // 30 absent at least in Android Game
- optional Sport sport = 31;
- optional float ps_f32 = 32;
- optional uint32 ps_f33 = 33;
- optional float dist_lat = 34; //= BikeEntity.field_F00 (=219.56387 and incr if moving: actual distance moved included lateral movement)
- optional int32 world = 35;
- optional uint32 ps_f36 = 36; // = f(BikeEntity.field_2a28) BikeEntity::CreateNewPacket
- optional uint32 ps_f37 = 37; // = f(BikeEntity.field_2a28) BikeEntity::CreateNewPacket
- optional bool canSteer = 38; // = BikeEntity.m_canSteer
- optional int32 route = 39;
- }
- message ClientToServer {
- required int64 server_realm = 1; //UdpClient::sendDisconnectedClientToServer: -1. Otherwise g_CurrentServerRealmID (RealmID or 0 if not connected yet)
- required int64 player_id = 2;
- optional int64 world_time = 3;
- optional uint32 seqno = 4;
- optional uint32 cts_f5 = 5;
- optional int64 cts_f6 = 6;
- required PlayerState state = 7;
- optional bool cts_f8 = 8;
- optional bool cts_f9 = 9;
- required int64 last_update = 10;
- optional bool cts_f11 = 11;
- required int64 last_player_update = 12;
- optional int64 larg_wa_time = 13; //TcpClient::sayHello: LargestWorldAttributeTimestamp
- optional bool cts_f14 = 14;
- repeated int64 subsSegments = 15; //subscribed segment ids? TcpClient::sayHello, TcpClient::sendSubscribeToSegment
- repeated int64 unsSegments = 16; //unsubscribed segment ids? TcpClient::processSegmentUnsubscription
- }
- message PlayerSummary {
- optional int32 plsu_f1 = 1;
- optional int32 plsu_f2 = 2;
- optional int32 plsu_f3 = 3;
- optional int32 plsu_f4 = 4;
- }
- message PlayerSummaries {
- optional sint64 plsus_f1 = 1; //stored as int32
- optional sint64 plsus_f2 = 2; //stored as int32
- optional sint32 plsus_f3 = 3;
- optional sint32 plsus_f4 = 4;
- optional int32 plsus_f5 = 5;
- optional int32 plsus_f6 = 6;
- optional int32 plsus_f7 = 7;
- repeated PlayerSummary player_summaries = 8;
- }
- message RelayAddress {
- optional int32 lb_realm = 1; // load balancing cluster: server realm or 0 (generic)
- optional int32 lb_course = 2; // load balancing cluster: course id
- optional string ip = 3;
- optional int32 port = 4;
- optional float ra_f5 = 5; //used when appropriate server selection occurs (RelayAddressService::getAddress)
- optional float ra_f6 = 6; //used when appropriate server selection occurs (RelayAddressService::getAddress)
- }
- message UdpConfig {
- repeated RelayAddress relay_addresses = 1;
- optional int32 uc_f2 = 2; //=10?
- optional int32 uc_f3 = 3; //=30?
- optional int32 uc_f4 = 4; //=3?
- }
- message RelayAddressesVOD {
- optional int32 lb_realm = 1; // load balancing cluster: server realm or 0 (generic)
- optional int32 lb_course = 2; // load balancing cluster: course id
- repeated RelayAddress relay_addresses = 3;
- optional bool rav_f4 = 4; //server selection method: true->higher (ra_f5, ra_f6), false->nearest (ra_f5, ra_f6)
- }
- message UdpConfigVOD {
- repeated RelayAddressesVOD relay_addresses_vod = 1;
- optional int32 port = 2;
- optional int64 ucv_f3 = 3;
- optional int64 ucv_f4 = 4;
- optional float ucv_f5 = 5;
- optional float ucv_f6 = 6;
- }
- message PlayerRouteDistance {
- optional int32 player_id = 1; //BikeManager::FindBikeWithNetworkID
- optional float distance_covered = 2; //not sure
- optional int32 millisec_to_leader = 3; // ZNETWORK_INTERNAL_ProcessPlayerPackets
- }
- message EventSubgroupPlacements {
- optional int32 position = 1; //UdpStatistics::registerFanViewLatestPlayerStateInfo
- repeated PlayerRouteDistance player_rd1 = 2;
- repeated PlayerRouteDistance player_rd2 = 3;
- repeated PlayerRouteDistance eventRiderPosition = 4;
- repeated PlayerRouteDistance player_rd4 = 5;
- optional int32 eventTotalRiders = 6;
- optional int32 bikeNetworkId = 7;
- optional int32 millisec_to_leader = 8; //ZNETWORK_INTERNAL_ProcessPlayerPackets
- optional float esp_f9 = 9; //or fixed
- }
- enum IPProtocol {
- UDP = 1;
- TCP = 2;
- }
- enum ExpungeReason {
- NOT_EXPUNGED = 0;
- WORLD_FULL = 1;
- ROADS_CLOSED = 2;
- }
- message ServerToClient {
- optional int64 server_realm = 1;
- optional int64 player_id = 2;
- optional int64 world_time = 3;
- optional int32 seqno = 4;
- optional int32 stc_f5 = 5; //low-priority world time sync algo (not investigated yet, maybe deprecated) in WorldClockService::calculateOneLegLatency
- // 6,7: absent
- repeated PlayerState states = 8;
- repeated WorldAttribute updates = 9;
- repeated int64 stc_f10 = 10;
- optional bool stc_f11 = 11; //=true???
- optional string zc_local_ip = 12;
- optional int64 stc_f13 = 13;
- optional int32 zwifters = 14;
- optional int32 zc_local_port = 15;
- optional IPProtocol zc_protocol = 16;
- optional int64 cts_latency = 17; //high-priority world time sync algo in WorldClockService::calculateOneLegLatency
- optional int32 num_msgs = 18;
- optional int32 msgnum = 19;
- optional bool hasSimultLogin = 20; //UdpClient::disconnectionRequested due to simultaneous login (1); OR simultaneous login ceased (0)
- optional PlayerSummaries player_summaries = 21; //tag426
- // 22 absent
- optional EventSubgroupPlacements ev_subgroup_ps = 23; //tag442
- optional UdpConfig udp_config = 24; //tag450
- optional UdpConfigVOD udp_config_vod_1 = 25; //tag458
- optional ExpungeReason expungeReason = 26; //tag464 UdpClient::receivedExpungeReason
- optional UdpConfigVOD udp_config_vod_2 = 27; //tag474
- repeated PlayerState player_states = 28; //tag482
- optional TcpConfig tcp_config = 29; //tag490
- repeated int64 ackSubsSegm = 30; //tag496 TcpClient::processSubscribedSegment
- optional uint32 stc_f31 = 31; //tag508
- optional bytes zc_key = 32; //tag642
- }
- message Ghost { //not from the Zwift game, zoffline-specific!
- required int32 player_id = 1;
- repeated PlayerState states = 2;
- }
- message RideOn {
- required int64 player_id = 1;
- required int64 to_player_id = 2;
- required string firstName = 3;
- required string lastName = 4;
- required int32 countryCode = 5;
- }
|