loadsa work
[carveJwlIkooP6JGAAIwe30JlM.git] / network.h
1 #ifndef NETWORK_H
2 #define NETWORK_H
3
4 #include "vg/vg_stdint.h"
5 #include "steam.h"
6 #include "network_msg.h"
7
8 /*
9 * Interface
10 */
11
12 /* Call it at start; Connects us to the gameserver */
13 static void network_init(void);
14
15 /* Run this from main loop */
16 static void network_update(void);
17
18 /* Call it at shutdown */
19 static void network_end(void);
20
21 /*
22 * Can buffer up a bunch of these by calling many times, they will be
23 * sent at the next connection
24 */
25 static void network_submit_highscore( u32 trackid, u16 points, u16 time );
26
27 /*
28 * Game endpoints are provided with the same names to allow running without a
29 * network connection.
30 */
31 #ifdef SR_NETWORKED
32
33 /*
34 * Runtime connection stuff
35 */
36 static u8 steam_app_ticket[ 1024 ];
37 static u32 steam_app_ticket_length;
38
39 static HSteamNetConnection cremote;
40 static ESteamNetworkingConnectionState cremote_state =
41 k_ESteamNetworkingConnectionState_None;
42
43 /*
44 * Implementation
45 */
46
47 static void scores_update(void);
48
49 static void on_auth_ticket_recieved( void *result, void *context )
50 {
51 EncryptedAppTicketResponse_t *response = result;
52
53 if( response->m_eResult == k_EResultOK )
54 {
55 vg_info( " New app ticket ready\n" );
56 }
57 else
58 {
59 vg_warn( " Could not request new encrypted app ticket (%u)\n",
60 response->m_eResult );
61 }
62
63 if( SteamAPI_ISteamUser_GetEncryptedAppTicket( hSteamUser,
64 steam_app_ticket,
65 vg_list_size(steam_app_ticket),
66 &steam_app_ticket_length ))
67 {
68 vg_success( " Loaded app ticket (%u bytes)\n", steam_app_ticket_length );
69 }
70 else
71 {
72 vg_error( " No ticket availible\n" );
73 steam_app_ticket_length = 0;
74 }
75 }
76
77 static void request_auth_ticket(void)
78 {
79 /*
80 * TODO Check for one thats cached on the disk and load it.
81 * This might be OK though because steam seems to cache the result
82 */
83
84 vg_info( "Requesting new authorization ticket\n" );
85 steam_async *call = steam_new_async();
86 call->data = NULL;
87 call->p_handler = on_auth_ticket_recieved;
88 call->id = SteamAPI_ISteamUser_RequestEncryptedAppTicket( hSteamUser,
89 NULL, 0 );
90 }
91
92 static void server_connect(void)
93 {
94 /* Connect to server if not connected */
95
96 SteamNetworkingIPAddr remoteAddr;
97
98 #define USE_LOCALHOST
99 #ifdef USE_LOCALHOST
100 SteamAPI_SteamNetworkingIPAddr_SetIPv6LocalHost( &remoteAddr, 27402 );
101 #else
102 const char *server_lon1 = "46.101.34.155:27402";
103 SteamAPI_SteamNetworkingIPAddr_ParseString( &remoteAddr, server_lon1 );
104 #endif
105
106 char buf[256];
107 SteamAPI_SteamNetworkingIPAddr_ToString( &remoteAddr, buf, 256, 1 );
108 vg_info( "connect to: %s\n", buf );
109
110 cremote = SteamAPI_ISteamNetworkingSockets_ConnectByIPAddress(
111 hSteamNetworkingSockets, &remoteAddr, 0, NULL );
112 }
113
114 static void send_auth_ticket(void)
115 {
116 u32 size = sizeof(netmsg_auth) + steam_app_ticket_length;
117 netmsg_auth *auth = malloc(size);
118
119 auth.inetmsg_id = k_inetmsg_auth;
120 auth.ticket_length = steam_app_ticket_length;
121 for( int i=0; i<steam_app_ticket_length; i++ )
122 auth.ticket[i] = steam_app_ticket[i];
123
124 SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
125 hSteamNetworkingSockets, cremote, auth, size,
126 k_nSteamNetworkingSend_Reliable, NULL );
127
128 free( auth );
129 }
130
131 static void scores_update(void)
132 {
133 vg_log( "scores_update()\n" );
134
135 if( cremote_state == k_ESteamNetworkingConnectionState_Connected )
136 {
137 /*
138 * request updated scores, this does not require any authentication.
139 */
140 netmsg_scores_request req;
141 req.inetmsg_id = k_inetmsg_scores_request;
142
143 SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
144 hSteamNetworkingSockets, cremote, &req,
145 sizeof(netmsg_scores_request),
146 k_nSteamNetworkingSend_Reliable, NULL );
147
148 /*
149 * Send record update, it requires authentication
150 */
151 if( steam_app_ticket_length )
152 {
153 }
154 }
155 else
156 {
157 /*
158 * if we are not connected, make a connection to the server and then in
159 * the future this function will be called again when it is connected
160 */
161 server_connect();
162 }
163 }
164
165 static void poll_connection(void)
166 {
167 SteamNetworkingMessage_t *messages[32];
168 int len;
169
170 while(1)
171 {
172 len = SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnConnection(
173 hSteamNetworkingSockets, cremote, messages, vg_list_size(messages));
174
175 if( len <= 0 )
176 return;
177
178 for( int i=0; i<len; i++ )
179 {
180 SteamNetworkingMessage_t *msg = messages[i];
181
182 if( msg->m_cbSize < sizeof(netmsg_blank) )
183 {
184 vg_warn( "Discarding message (too small: %d)\n",
185 msg->m_cbSize );
186 continue;
187 }
188
189 netmsg_blank *tmp = msg->m_pData;
190 if( tmp->inetmsg_id == k_inetmsg_scores_info )
191 {
192 netmsg_scores_info *info = msg->m_pData;
193 vg_log( "Recieved %u score records\n", info->record_count );
194
195 SteamAPI_ISteamNetworkingSockets_CloseConnection(
196 hSteamNetworkingSockets, cremote, 0, NULL, 1 );
197 cremote_state = k_ESteamNetworkingConnectionState_None;
198 }
199
200 SteamAPI_SteamNetworkingMessage_t_Release( msg );
201 }
202 }
203 }
204
205 static u64 in_server_ticks( double seconds )
206 {
207 return (u64)(seconds / 0.1);
208 }
209
210 static void on_server_connect_status( CallbackMsg_t *msg )
211 {
212 SteamNetConnectionStatusChangedCallback_t *info = (void *)msg->m_pubParam;
213 vg_info( " Connection status changed for %lu\n", info->m_hConn );
214 vg_info( " %s -> %s\n",
215 string_ESteamNetworkingConnectionState(info->m_info.m_eState),
216 string_ESteamNetworkingConnectionState(info->m_eOldState) );
217
218 if( info->m_hConn == cremote )
219 {
220 cremote_state = info->m_info.m_eState;
221 if( info->m_info.m_eState ==
222 k_ESteamNetworkingConnectionState_Connected )
223 {
224 vg_success(" Connected to remote server\n");
225 scores_update();
226 }
227 }
228 else
229 {
230 vg_warn( " Recieved signal from unknown connection\n" );
231 }
232 }
233
234 static void network_init(void)
235 {
236 if( steam_ready )
237 {
238 steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack,
239 on_server_connect_status );
240 request_auth_ticket();
241 }
242 }
243
244 static void network_update(void)
245 {
246 if( steam_ready )
247 {
248 static double last_update = -9000.0;
249 poll_connection();
250
251 if( vg_time > (last_update + 60.0) )
252 {
253 last_update = vg_time;
254 scores_update();
255 }
256 }
257 }
258
259 static void network_end(void)
260 {
261 /* TODO: Fire off any buffered highscores that need to be setn */
262 }
263
264 #endif
265 #endif /* NETWORK_H */