test network 5
[carveJwlIkooP6JGAAIwe30JlM.git] / player_remote.c
1 #include "player_remote.h"
2
3 static void player_remote_unwatch( struct network_player *player ){
4 addon_cache_unwatch( k_addon_type_player, player->playermodel_view_slot );
5 addon_cache_unwatch( k_addon_type_board, player->board_view_slot );
6 }
7
8 static void player_remote_clear( struct network_player *player ){
9 player_remote_unwatch( player );
10 memset( player, 0, sizeof(*player) );
11 strcpy( player->username, "unknown" );
12 player->subsystem = k_player_subsystem_invalid;
13 }
14
15 static void player_remote_rx_200_300( SteamNetworkingMessage_t *msg ){
16 netmsg_blank *tmp = msg->m_pData;
17
18 if( tmp->inetmsg_id == k_inetmsg_playerjoin ){
19 netmsg_playerjoin *playerjoin = msg->m_pData;
20 if( !packet_minsize( msg, sizeof(*playerjoin) )) return;
21
22 if( playerjoin->index < vg_list_size(netplayers.list) ){
23 struct network_player *player = &netplayers.list[ playerjoin->index ];
24 player_remote_clear( player );
25 player->active = 1;
26
27 /* TODO: interpret the uids */
28 player->board_view_slot = 0;
29 player->playermodel_view_slot = 0;
30
31 vg_strncpy( playerjoin->username, player->username,
32 sizeof(player->username), k_strncpy_always_add_null );
33
34 vg_info( "#%u joined with name: %s\n", player->username );
35 }
36 else {
37 vg_error( "inetmsg_playerjoin: player index out of range\n" );
38 }
39 }
40 else if( tmp->inetmsg_id == k_inetmsg_playerleave ){
41 netmsg_playerleave *playerleave = msg->m_pData;
42 if( !packet_minsize( msg, sizeof(*playerleave) )) return;
43
44 if( playerleave->index < vg_list_size(netplayers.list) ){
45 struct network_player *player = &netplayers.list[ playerleave->index ];
46 player_remote_unwatch( player );
47 player->active = 0;
48 vg_info( "player leave (%d)\n", playerleave->index );
49 }
50 else {
51 vg_error( "inetmsg_playerleave: player index out of range\n" );
52 }
53 }
54 else if( tmp->inetmsg_id == k_inetmsg_playerusername ){
55 netmsg_playerusername *update = msg->m_pData;
56 if( !packet_minsize( msg, sizeof(*update) )) return;
57
58 if( update->index < vg_list_size(netplayers.list) ){
59 struct network_player *player = &netplayers.list[ update->index ];
60 vg_strncpy( update->username, player->username,
61 sizeof(player->username), k_strncpy_always_add_null );
62
63 vg_info( "#%u changed username: %s\n", player->username );
64 }
65 else {
66 vg_error( "inetmsg_playerleave: player index out of range\n" );
67 }
68 }
69 else if( tmp->inetmsg_id == k_inetmsg_playerframe ){
70 u32 datasize = msg->m_cbSize - sizeof(netmsg_playerframe);
71
72 if( datasize > sizeof(netplayers.list[0].animdata) ){
73 vg_error( "Player frame data exceeds animdata size\n" );
74 return;
75 }
76
77 netmsg_playerframe *frame = msg->m_pData;
78 if( frame->client >= vg_list_size(netplayers.list) ){
79 vg_error( "inetmsg_playerframe: player index out of range\n" );
80 return;
81 }
82
83 if( frame->subsystem >= k_player_subsystem_max ){
84 vg_error( "inetmsg_playerframe: subsystem out of range\n" );
85 return;
86 }
87
88 struct network_player *player = &netplayers.list[ frame->client ];
89 memcpy( &player->animdata, frame->animdata, datasize );
90 player->subsystem = frame->subsystem;
91 player->down_bytes += msg->m_cbSize;
92 }
93 }
94
95 static void remote_player_send_playerframe(void){
96 u8 sysid = localplayer.subsystem;
97 if( sysid >= k_player_subsystem_max ) return;
98
99 struct player_subsystem_interface *sys = player_subsystems[sysid];
100
101 if( sys->animator_size ){
102 u32 size = sizeof(netmsg_playerframe)+sys->animator_size;
103 netmsg_playerframe *frame = alloca(size);
104 frame->inetmsg_id = k_inetmsg_playerframe;
105 frame->client = 0;
106 frame->subsystem = localplayer.subsystem;
107 memcpy( frame->animdata, sys->animator_data, sys->animator_size );
108
109 netplayers.up_bytes += size;
110
111 SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
112 hSteamNetworkingSockets, network_client.remote,
113 frame, size,
114 k_nSteamNetworkingSend_Unreliable, NULL );
115 }
116 }
117
118 static void remote_player_debug_update(void){
119 if( (vg.time_real - netplayers.last_data_measurement) > 1.0 ){
120 netplayers.last_data_measurement = vg.time_real;
121 u32 total_down = 0;
122
123 for( u32 i=0; i<vg_list_size(netplayers.list); i++ ){
124 struct network_player *player = &netplayers.list[i];
125 if( player->active ){
126 total_down += player->down_bytes;
127 player->down_kbs = ((f32)player->down_bytes)/1024.0f;
128 player->down_bytes = 0;
129 }
130 }
131
132 netplayers.down_kbs = ((f32)total_down)/1024.0f;
133 netplayers.up_kbs = ((f32)netplayers.up_bytes)/1024.0f;
134 netplayers.up_bytes = 0;
135 }
136 }
137
138 static void remote_player_network_imgui(void){
139 if( !network_client.network_info )
140 return;
141
142 ui_rect panel = { (vg.window_x / 2) - 200, 0, 400, 600 };
143 ui_fill( panel, (ui_colour(k_ui_bg)&0x00ffffff)|0x50000000 );
144
145 char buf[512];
146 const char *netstatus = "PROGRAMMING ERROR";
147
148 struct { enum ESteamNetworkingConnectionState state; const char *str; }
149 states[] = {
150 { k_ESteamNetworkingConnectionState_None, "None" },
151 { k_ESteamNetworkingConnectionState_Connecting,
152 (const char *[]){"Connecting -",
153 "Connecting /",
154 "Connecting |",
155 "Connecting \\",
156 }[(u32)(vg.time_real/0.25) & 0x3 ] },
157 { k_ESteamNetworkingConnectionState_FindingRoute, "Finding Route" },
158 { k_ESteamNetworkingConnectionState_Connected, "Connected" },
159 { k_ESteamNetworkingConnectionState_ClosedByPeer, "Closed by peer" },
160 { k_ESteamNetworkingConnectionState_ProblemDetectedLocally,
161 "Problem Detected Locally" },
162 { k_ESteamNetworkingConnectionState_FinWait, "Fin Wait" },
163 { k_ESteamNetworkingConnectionState_Linger, "Linger" },
164 { k_ESteamNetworkingConnectionState_Dead, "Dead" }
165 };
166 for( u32 i=0; i<vg_list_size(states); i ++ ){
167 if( states[i].state == network_client.state ){
168 netstatus = states[i].str;
169 break;
170 }
171 }
172 snprintf( buf, 512, "Network: %s", netstatus );
173 ui_info( panel, buf );
174 ui_info( panel, "---------------------" );
175
176 if( network_client.state == k_ESteamNetworkingConnectionState_Connected ){
177 ui_info( panel, "#-1: localplayer" );
178
179 snprintf( buf, 512, "U%.1f/D%.1fkbs",
180 netplayers.up_kbs, netplayers.down_kbs );
181 ui_info( panel, buf );
182
183 for( u32 i=0; i<vg_list_size(netplayers.list); i++ ){
184 struct network_player *player = &netplayers.list[i];
185 if( player->active ){
186 const char *sysname = "invalid";
187
188 if( player->subsystem < k_player_subsystem_max ){
189 sysname = player_subsystems[ player->subsystem ]->name;
190 }
191 snprintf( buf, 512, "#%u: %s [%s] D%.1fkbs",
192 i, player->username, sysname, player->down_kbs );
193 ui_info( panel, buf );
194 }
195 }
196 }
197 else {
198 ui_info( panel, "offline" );
199 }
200 }