1 #include "player_remote.h"
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
);
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
;
15 static void player_remote_rx_200_300( SteamNetworkingMessage_t
*msg
){
16 netmsg_blank
*tmp
= msg
->m_pData
;
18 if( tmp
->inetmsg_id
== k_inetmsg_playerjoin
){
19 netmsg_playerjoin
*playerjoin
= msg
->m_pData
;
20 if( !packet_minsize( msg
, sizeof(*playerjoin
) )) return;
22 if( playerjoin
->index
< vg_list_size(netplayers
.list
) ){
23 struct network_player
*player
= &netplayers
.list
[ playerjoin
->index
];
24 player_remote_clear( player
);
27 /* TODO: interpret the uids */
28 player
->board_view_slot
= 0;
29 player
->playermodel_view_slot
= 0;
31 vg_strncpy( playerjoin
->username
, player
->username
,
32 sizeof(player
->username
), k_strncpy_always_add_null
);
34 vg_info( "#%u joined with name: %s\n",
35 playerjoin
->index
, player
->username
);
38 vg_error( "inetmsg_playerjoin: player index out of range\n" );
41 else if( tmp
->inetmsg_id
== k_inetmsg_playerleave
){
42 netmsg_playerleave
*playerleave
= msg
->m_pData
;
43 if( !packet_minsize( msg
, sizeof(*playerleave
) )) return;
45 if( playerleave
->index
< vg_list_size(netplayers
.list
) ){
46 struct network_player
*player
= &netplayers
.list
[ playerleave
->index
];
47 player_remote_unwatch( player
);
49 vg_info( "player leave (%d)\n", playerleave
->index
);
52 vg_error( "inetmsg_playerleave: player index out of range\n" );
55 else if( tmp
->inetmsg_id
== k_inetmsg_playerusername
){
56 netmsg_playerusername
*update
= msg
->m_pData
;
57 if( !packet_minsize( msg
, sizeof(*update
) )) return;
59 if( update
->index
< vg_list_size(netplayers
.list
) ){
60 struct network_player
*player
= &netplayers
.list
[ update
->index
];
61 vg_strncpy( update
->username
, player
->username
,
62 sizeof(player
->username
), k_strncpy_always_add_null
);
64 vg_info( "#%u changed username: %s\n", player
->username
);
67 vg_error( "inetmsg_playerleave: player index out of range\n" );
70 else if( tmp
->inetmsg_id
== k_inetmsg_playerframe
){
71 u32 datasize
= msg
->m_cbSize
- sizeof(netmsg_playerframe
);
73 if( datasize
> sizeof(netplayers
.list
[0].animdata
) ){
74 vg_error( "Player frame data exceeds animdata size\n" );
78 netmsg_playerframe
*frame
= msg
->m_pData
;
79 if( frame
->client
>= vg_list_size(netplayers
.list
) ){
80 vg_error( "inetmsg_playerframe: player index out of range\n" );
84 if( frame
->subsystem
>= k_player_subsystem_max
){
85 vg_error( "inetmsg_playerframe: subsystem out of range\n" );
89 struct network_player
*player
= &netplayers
.list
[ frame
->client
];
90 memcpy( &player
->animdata
, frame
->animdata
, datasize
);
91 player
->subsystem
= frame
->subsystem
;
92 player
->down_bytes
+= msg
->m_cbSize
;
96 static void remote_player_send_playerframe(void){
97 u8 sysid
= localplayer
.subsystem
;
98 if( sysid
>= k_player_subsystem_max
) return;
100 struct player_subsystem_interface
*sys
= player_subsystems
[sysid
];
102 if( sys
->animator_size
){
103 u32 size
= sizeof(netmsg_playerframe
)+sys
->animator_size
;
104 netmsg_playerframe
*frame
= alloca(size
);
105 frame
->inetmsg_id
= k_inetmsg_playerframe
;
107 frame
->subsystem
= localplayer
.subsystem
;
108 memcpy( frame
->animdata
, sys
->animator_data
, sys
->animator_size
);
110 netplayers
.up_bytes
+= size
;
112 SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
113 hSteamNetworkingSockets
, network_client
.remote
,
115 k_nSteamNetworkingSend_Unreliable
, NULL
);
119 static void remote_player_debug_update(void){
120 if( (vg
.time_real
- netplayers
.last_data_measurement
) > 1.0 ){
121 netplayers
.last_data_measurement
= vg
.time_real
;
124 for( u32 i
=0; i
<vg_list_size(netplayers
.list
); i
++ ){
125 struct network_player
*player
= &netplayers
.list
[i
];
126 if( player
->active
){
127 total_down
+= player
->down_bytes
;
128 player
->down_kbs
= ((f32
)player
->down_bytes
)/1024.0f
;
129 player
->down_bytes
= 0;
133 netplayers
.down_kbs
= ((f32
)total_down
)/1024.0f
;
134 netplayers
.up_kbs
= ((f32
)netplayers
.up_bytes
)/1024.0f
;
135 netplayers
.up_bytes
= 0;
139 static void remote_player_network_imgui( m4x4f pv
){
140 if( !network_client
.network_info
)
143 ui_rect panel
= { (vg
.window_x
/ 2) - 200, 0, 400, 600 };
144 ui_fill( panel
, (ui_colour(k_ui_bg
)&0x00ffffff)|0x50000000 );
147 const char *netstatus
= "PROGRAMMING ERROR";
149 struct { enum ESteamNetworkingConnectionState state
; const char *str
; }
151 { k_ESteamNetworkingConnectionState_None
, "None" },
152 { k_ESteamNetworkingConnectionState_Connecting
,
153 (const char *[]){"Connecting -",
157 }[(u32
)(vg
.time_real
/0.25) & 0x3 ] },
158 { k_ESteamNetworkingConnectionState_FindingRoute
, "Finding Route" },
159 { k_ESteamNetworkingConnectionState_Connected
, "Connected" },
160 { k_ESteamNetworkingConnectionState_ClosedByPeer
, "Closed by peer" },
161 { k_ESteamNetworkingConnectionState_ProblemDetectedLocally
,
162 "Problem Detected Locally" },
163 { k_ESteamNetworkingConnectionState_FinWait
, "Fin Wait" },
164 { k_ESteamNetworkingConnectionState_Linger
, "Linger" },
165 { k_ESteamNetworkingConnectionState_Dead
, "Dead" }
167 for( u32 i
=0; i
<vg_list_size(states
); i
++ ){
168 if( states
[i
].state
== network_client
.state
){
169 netstatus
= states
[i
].str
;
173 snprintf( buf
, 512, "Network: %s", netstatus
);
174 ui_info( panel
, buf
);
175 ui_info( panel
, "---------------------" );
177 if( network_client
.state
== k_ESteamNetworkingConnectionState_Connected
){
178 ui_info( panel
, "#-1: localplayer" );
180 snprintf( buf
, 512, "U%.1f/D%.1fkbs",
181 netplayers
.up_kbs
, netplayers
.down_kbs
);
182 ui_info( panel
, buf
);
184 for( u32 i
=0; i
<vg_list_size(netplayers
.list
); i
++ ){
185 struct network_player
*player
= &netplayers
.list
[i
];
186 if( player
->active
){
187 const char *sysname
= "invalid";
189 if( player
->subsystem
< k_player_subsystem_max
){
190 sysname
= player_subsystems
[ player
->subsystem
]->name
;
192 snprintf( buf
, 512, "#%u: %s [%s] D%.1fkbs",
193 i
, player
->username
, sysname
, player
->down_kbs
);
194 ui_info( panel
, buf
);
196 v4f wpos
= { 0.0f
, 2.0f
, 0.0f
, 1.0f
};
197 m4x3_mulv( netplayers
.final_mtx
[0], wpos
, wpos
);
198 m4x4_mulv( pv
, wpos
, wpos
);
200 if( wpos
[3] > 0.0f
){
201 v2_muls( wpos
, (1.0f
/wpos
[3]) * 0.5f
, wpos
);
202 v2_add( wpos
, (v2f
){ 0.5f
, 0.5f
}, wpos
);
205 wr
[0] = vg_clampf(wpos
[0] * vg
.window_x
, -32000.0f
,32000.0f
);
206 wr
[1] = vg_clampf((1.0f
-wpos
[1]) * vg
.window_y
,
210 ui_fill( wr
, (ui_colour(k_ui_bg
)&0x00ffffff)|0x50000000 );
211 ui_text( wr
, buf
, 1, k_ui_align_middle_center
, 0 );
217 ui_info( panel
, "offline" );