begin network integration
[carveJwlIkooP6JGAAIwe30JlM.git] / server.c
1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
2
3 /*
4 * This server application requires steamclient.so to be present in the
5 * executable directory. This is not provided by vg system, it must be
6 * downloaded via steamcmd. It will likely be somewhere in ~/.steam/ ...
7 */
8
9 #define _DEFAULT_SOURCE
10 #include <unistd.h>
11 #include <signal.h>
12
13 volatile sig_atomic_t sig_stop;
14
15 void inthandler( int signum )
16 {
17 sig_stop = 1;
18 }
19
20 #define VG_SERVER
21 #include "vg/vg.h"
22 #include "vg/vg_steam.h"
23 #include "vg/vg_steam_networking.h"
24 #include "vg/vg_steam_http.h"
25 #include "vg/vg_steam_auth.h"
26 #include "network_msg.h"
27
28 void *hSteamHTTP,
29 *hSteamNetworkingSockets;
30
31 u8 steam_symetric_key[ k_nSteamEncryptedAppTicketSymmetricKeyLen ];
32 HSteamNetPollGroup client_pollgroup;
33
34 static void recieve_http( void *callresult, void *context )
35 {
36 HTTPRequestCompleted_t *result = callresult;
37
38 HTTPRequestHandle request = result->m_hRequest;
39 u32 size = 0;
40
41 SteamAPI_ISteamHTTP_GetHTTPResponseBodySize( hSteamHTTP, request, &size );
42
43 u8 *buffer = malloc( size );
44 SteamAPI_ISteamHTTP_GetHTTPResponseBodyData(
45 hSteamHTTP, request, buffer, size );
46
47 buffer[size-1] = '\0';
48 vg_info( "%s\n", (char *)buffer );
49
50 free( buffer );
51 SteamAPI_ISteamHTTP_ReleaseHTTPRequest( hSteamHTTP, result->m_hRequest );
52 }
53
54 static void new_client_connecting( HSteamNetConnection client )
55 {
56 EResult accept_status = SteamAPI_ISteamNetworkingSockets_AcceptConnection(
57 hSteamNetworkingSockets, client );
58
59 if( accept_status == k_EResultOK )
60 {
61 vg_success( "Accepted client (id: %u)\n", client );
62 SteamAPI_ISteamNetworkingSockets_SetConnectionPollGroup(
63 hSteamNetworkingSockets,
64 client, client_pollgroup );
65 }
66 else
67 {
68 vg_warn( "Error accepting client (id: %u)\n", client );
69 }
70 }
71
72 static void on_auth_status( CallbackMsg_t *msg )
73 {
74 SteamNetAuthenticationStatus_t *info = (void *)msg->m_pubParam;
75 vg_info( " Authentication availibility: %s\n",
76 string_ESteamNetworkingAvailability(info->m_eAvail) );
77 vg_info( " %s\n", info->m_debugMsg );
78 }
79
80 static void on_connect_status( CallbackMsg_t *msg )
81 {
82 SteamNetConnectionStatusChangedCallback_t *info = (void *)msg->m_pubParam;
83 vg_info( " Connection status changed for %lu\n", info->m_hConn );
84
85 vg_info( " %s -> %s\n",
86 string_ESteamNetworkingConnectionState(info->m_info.m_eState),
87 string_ESteamNetworkingConnectionState(info->m_eOldState) );
88
89 if( info->m_info.m_eState==k_ESteamNetworkingConnectionState_Connecting )
90 {
91 new_client_connecting( info->m_hConn );
92 }
93 }
94
95 static void poll_connections(void)
96 {
97 SteamNetworkingMessage_t *messages[32];
98 int len;
99
100 while(1)
101 {
102 len = SteamAPI_ISteamNetworkingSockets_ReceiveMessagesOnPollGroup(
103 hSteamNetworkingSockets,
104 client_pollgroup, messages, vg_list_size(messages) );
105
106 if( len <= 0 )
107 return;
108
109 for( int i=0; i<len; i++ )
110 {
111 SteamNetworkingMessage_t *msg = messages[i];
112
113 if( msg->m_cbSize < sizeof(netmsg_blank) )
114 {
115 vg_warn( "Discarding message (too small: %d)\n",
116 msg->m_cbSize );
117 continue;
118 }
119
120 netmsg_blank *tmp = msg->m_pData;
121 if( tmp->inetmsg_id == k_inetmsg_scores_request )
122 {
123 vg_log( "Recieved score request, sending records. (id: %u)\n",
124 msg->m_conn );
125
126 /* Send back current scores */
127 u32 data_size = sizeof(netmsg_scores_info) +
128 0*sizeof(struct netmsg_score_record);
129 netmsg_scores_info *return_info = malloc( data_size );
130
131 return_info->inetmsg_id = k_inetmsg_scores_info;
132 return_info->record_count = 0;
133
134 SteamAPI_ISteamNetworkingSockets_SendMessageToConnection(
135 hSteamNetworkingSockets, msg->m_conn,
136 return_info, data_size,
137 k_nSteamNetworkingSend_Reliable, NULL );
138 }
139
140 SteamAPI_SteamNetworkingMessage_t_Release( msg );
141 }
142 }
143 }
144
145 int main( int argc, char *argv[] )
146 {
147 steamworks_ensure_txt( "2103940" );
148 signal( SIGINT, inthandler );
149
150 if( !vg_load_steam_symetric_key( "application_key", steam_symetric_key ) )
151 return 0;
152
153 if( !SteamGameServer_Init( 0, 27400, 27401, eServerModeAuthentication,
154 "1.0.0.0" ) )
155 {
156 vg_error( "SteamGameServer_Init failed\n" );
157 return 0;
158 }
159
160 void *hSteamGameServer = SteamAPI_SteamGameServer();
161 SteamAPI_ISteamGameServer_LogOnAnonymous( hSteamGameServer );
162
163 SteamAPI_ManualDispatch_Init();
164 HSteamPipe hsteampipe = SteamGameServer_GetHSteamPipe();
165
166 //hSteamHTTP = SteamAPI_SteamGameServerHTTP();
167 hSteamNetworkingSockets =
168 SteamAPI_SteamGameServerNetworkingSockets_SteamAPI();
169
170 /*
171 * Server code
172 */
173
174 steam_register_callback( k_iSteamNetAuthenticationStatus, on_auth_status );
175 steam_register_callback( k_iSteamNetConnectionStatusChangedCallBack,
176 on_connect_status );
177
178 vg_success( "Steamworks API running\n" );
179 steamworks_event_loop( hsteampipe );
180
181 /*
182 * Create a listener
183 */
184
185 HSteamListenSocket listener;
186 SteamNetworkingIPAddr localAddr;
187 SteamAPI_SteamNetworkingIPAddr_Clear( &localAddr );
188 localAddr.m_port = 27402;
189
190 listener = SteamAPI_ISteamNetworkingSockets_CreateListenSocketIP(
191 hSteamNetworkingSockets, &localAddr, 0, NULL );
192 client_pollgroup = SteamAPI_ISteamNetworkingSockets_CreatePollGroup(
193 hSteamNetworkingSockets );
194
195 #if 0
196 HTTPRequestHandle test_req = SteamAPI_ISteamHTTP_CreateHTTPRequest(
197 hSteamHTTP, k_EHTTPMethodGET,
198 "https://www.harrygodden.com/hello.txt" );
199
200 steam_async *call1 = steam_new_async();
201 call1->data = NULL;
202 call1->p_handler = recieve_http;
203 SteamAPI_ISteamHTTP_SendHTTPRequest( hSteamHTTP, test_req, &call1->id );
204 #endif
205
206 u64 server_ticks = 8000;
207
208 while( !sig_stop )
209 {
210 steamworks_event_loop( hsteampipe );
211 poll_connections();
212
213 usleep(100000);
214 server_ticks ++;
215 }
216
217 SteamAPI_ISteamNetworkingSockets_DestroyPollGroup( hSteamNetworkingSockets,
218 client_pollgroup );
219 SteamAPI_ISteamNetworkingSockets_CloseListenSocket(
220 hSteamNetworkingSockets, listener );
221
222 vg_info( "Shutting down\n..." );
223 SteamGameServer_Shutdown();
224
225 return 0;
226 }