203
Takes a pointer to a CSV formatted string to parse
204
And a pointer to a char array to store the result in
205
The pointer to the string will be moved to the end of the parsed field
207
int server_frame_t::parse_csv_field( char **c, char *field, size_t maxlen )
210
if ( c == NULL || *c == NULL ) {
214
n = strstr( *c, "\"," );
216
n = strstr( *c, "\"\n" );
218
// Copy everything up to end of string into field buffer
219
tstrncpy( field, *c + 1, min(strlen(*c + 1), maxlen) );
222
// Copy everything up to the EOL (\n) into field buffer
223
tstrncpy( field, *c + 1, min(n - *c, maxlen) );
225
// Move to end of string
229
tstrncpy(field, *c + 1, min(n - *c, maxlen));
230
// Move to start of next field
233
dbg->warning( "server_frame_t::parse_csv_field", "Parsed field: '%s'", field );
236
n = strstr( *c, "," );
237
// If n is NULL then this is the last field (no more field seperators)
239
dbg->warning( "server_frame_t::parse_csv_field", "last field" );
240
n = strstr( *c, "\n" );
242
// Copy everything up to end of string into field buffer
243
tstrncpy( field, *c, min(strlen(*c + 1), maxlen) );
246
// Copy everything up to the EOL (\n) into field buffer
247
tstrncpy( field, *c, min(n - *c + 1, maxlen) );
249
// Move to end of string
253
tstrncpy( field, *c, min(n - *c + 1, maxlen) );
254
// Move to start of next field
257
dbg->warning( "server_frame_t::parse_csv_field", "Parsed field: '%s'", field );
201
262
bool server_frame_t::update_serverlist( uint revision, const char *pakset )
264
dbg->warning( "server_frame_t::update_serverlist", "called with revision: %i, pakset: %s", revision, pakset );
203
265
// download list from main server
204
if( const char *err = network_download_http( "simutrans-germany.com:80", "/serverlist/data/serverlist.txt", "serverlist.txt" ) ) {
266
if ( const char *err = network_download_http(ANNOUNCE_SERVER, ANNOUNCE_LIST_URL, SERVER_LIST_FILE) ) {
205
267
dbg->warning( "server_frame_t::update_serverlist", "could not download list: %s", err );
209
FILE *fh = fopen( "serverlist.txt", "r" );
272
// name of server,dnsname.com:12345,4567,pak128 blah blah
273
FILE *fh = fopen( SERVER_LIST_FILE, "r" );
211
275
serverlist.clear_elements();
276
while ( !feof( fh ) ) {
214
fgets( line, sizeof(line), fh );
217
const char *c = strstr( line, " : " );
222
// get servername (and remove default port)
283
fgets( line, sizeof( line ), fh );
284
dbg->warning( "server_frame_t::update_serverlist", "parsing line: '%s'", line );
285
// if ( feof( fh ) ) { continue; }
287
// First field is display name of server
223
288
char servername[4096];
224
tstrncpy( servername, line, c-line+1 );
225
if( strcmp( servername+strlen(servername)-6, ":13353" )==0 ) {
226
servername[strlen(servername)-6] = 0;
229
// now program revision
230
const char *c2 = strstr( c+3, " : " );
234
uint32 serverrev = atol(c2);
235
if( revision!=0 && serverrev!=0 && revision!=serverrev ) {
289
ret = parse_csv_field( c, servername, 4096 );
290
if ( ret > 0 || servername[0] == '\0' ) { continue; }
292
// Second field is dns name of server (for connection)
293
char serverdns[4096];
294
ret = parse_csv_field( c, serverdns, 4096 );
295
if ( ret > 0 || servername[0] == '\0' ) { continue; }
296
// Strip default port
297
if ( strcmp(serverdns + strlen(serverdns) - 6, ":13353") == 0 ) {
298
dbg->warning( "server_frame_t::update_serverlist", "stripping default port from entry %s", serverdns );
299
serverdns[strlen(serverdns) - 6] = 0;
302
// Third field is server revision (use for filtering)
303
char serverrevision[100];
304
ret = parse_csv_field( c, serverrevision, 4096 );
305
if ( ret > 0 || servername[0] == '\0' ) { continue; }
306
uint32 serverrev = atol( serverrevision );
307
if ( revision != 0 && revision != serverrev ) {
236
308
// do not add mismatched servers
309
dbg->warning( "server_frame_t::update_serverlist", "revision %i does not match our revision (%i), skipping", serverrev, revision );
313
// Fourth field is server pakset (use for filtering)
314
char serverpakset[4096];
315
ret = parse_csv_field( c, serverpakset, 4096 );
316
if ( ret > 0 || servername[0] == '\0' ) { continue; }
240
317
// now check pakset match
242
if( strncmp( pakset, c2+3, strlen(pakset) ) ) {
318
if ( pakset != NULL ) {
319
if ( strncmp( pakset, serverpakset, strlen( pakset ) ) ) {
320
dbg->warning( "server_frame_t::update_serverlist", "pakset '%s' does not match our pakset ('%s'), skipping", serverpakset, pakset );
325
char serverentry[4096];
326
// const char *format = "%s (%s)";
327
// sprintf(serverentry, format, servername, serverdns);
328
const char *format = "%s";
329
sprintf( serverentry, format, serverdns );
248
serverlist.append_element( new gui_scrolled_list_t::var_text_scrollitem_t( servername, COL_BLUE ) );
333
// TODO - Need to decouple the text which is displayed in the listing box from the actual DNS/IP entry which is used to connect to the server in question
335
serverlist.append_element( new gui_scrolled_list_t::var_text_scrollitem_t( serverentry, COL_BLUE ) );
336
dbg->warning( "server_frame_t::update_serverlist", "Appended %s to list", serverentry );
338
// Clean up, remove temp file used for recv. listings
251
remove( "serverlist.txt" );
340
remove( SERVER_LIST_FILE );
252
341
serverlist.set_selection( -1 );