node-gamedig/reference/worldinconflict/qstat.txt
2014-02-03 16:04:51 -06:00

241 lines
6.2 KiB
Text

LICENSE: The Artistic License 2.0
/*
* qstat.h
* by Steve Jankowski
* steve@qstat.org
* http://www.qstat.org
*
* Copyright 1996,1997,1998,1999,2000,2001,2002 by Steve Jankowski
*/
{
/* World in Confict PROTOCOL */
WIC_PROTOCOL_SERVER, /* id */
"WICS", /* type_prefix */
"wics", /* type_string */
"-wics", /* type_option */
"World in Conflict", /* game_name */
0, /* master */
0, /* default_port */
0, /* port_offset */
TF_TCP_CONNECT|TF_QUERY_ARG_REQUIRED|TF_QUERY_ARG, /* flags */
"N/A", /* game_rule */
"WICPROTOCOL", /* template_var */
NULL, /* status_packet */
0, /* status_len */
NULL, /* player_packet */
0, /* player_len */
NULL, /* rule_packet */
0, /* rule_len */
NULL, /* master_packet */
0, /* master_len */
NULL, /* master_protocol */
NULL, /* master_query */
display_wic_player_info, /* display_player_func */
display_server_rules, /* display_rule_func */
raw_display_wic_player_info, /* display_raw_player_func */
raw_display_server_rules, /* display_raw_rule_func */
xml_display_wic_player_info, /* display_xml_player_func */
xml_display_server_rules, /* display_xml_rule_func */
send_wic_request_packet, /* status_query_func */
NULL, /* rule_query_func */
NULL, /* player_query_func */
deal_with_wic_packet, /* packet_func */
},
/*
* qstat 2.8
* by Steve Jankowski
*
* World in Conflict Protocol
* Copyright 2007 Steven Hartland
*
* Licensed under the Artistic License, see LICENSE.txt for license terms
*
*/
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "debug.h"
#include "qstat.h"
#include "packet_manip.h"
query_status_t send_wic_request_packet( struct qserver *server )
{
char buf[256];
int serverport = get_param_i_value( server, "port", 0 );
char *password = get_param_value( server, "password", "N/A" );
change_server_port( server, serverport, 1 );
if ( get_player_info )
{
server->flags |= TF_PLAYER_QUERY|TF_RULES_QUERY;
sprintf( buf, "%s\x0d\x0a/listsettings\x0d\x0a/listplayers\x0d\x0a/exit\x0d\x0a", password );
server->saved_data.pkt_index = 2;
}
else
{
server->flags |= TF_STATUS_QUERY;
sprintf( buf, "%s\x0d\x0a/listsettings\x0d\x0a/exit\x0d\x0a", password );
server->saved_data.pkt_index = 1;
}
return send_packet( server, buf, strlen( buf ) );
}
query_status_t deal_with_wic_packet( struct qserver *server, char *rawpkt, int pktlen )
{
char *s, *end, *team = NULL;
int mode = server->n_servers, slot, score;
char name[256], role[256];
debug( 2, "processing n_requests %d, retry1 %d, n_retries %d, delta %d", server->n_requests, server->retry1, n_retries, time_delta( &packet_recv_time, &server->packet_time1 ) );
server->ping_total += time_delta( &packet_recv_time, &server->packet_time1 );
server->n_requests++;
if ( 0 == pktlen )
{
// Invalid password
return REQ_ERROR;
}
gettimeofday( &server->packet_time1, NULL);
rawpkt[pktlen]= '\0';
end = &rawpkt[pktlen];
s = rawpkt;
while ( NULL != s )
{
int len = strlen( s );
*(s + len - 2) = '\0'; // strip off \x0D\x0A
debug( 2, "Line[%d]: %s", mode, s );
if ( 0 == mode )
{
// Settings
// TODO: make parse safe
if ( 0 == strncmp( s, "Settings: ", 9 ) )
{
// Server Rule
char *key = s + 10;
char *value = strchr( key, ' ' );
*value = '\0';
value++;
debug( 2, "key: '%s' = '%s'", key, value );
if ( 0 == strcmp( "myGameName", key ) )
{
server->server_name = strdup( value );
}
else if ( 0 == strcmp( "myMapFilename", key ) )
{
server->map_name = strdup( value );
}
else if ( 0 == strcmp( "myMaxPlayers", key ) )
{
server->max_players = atoi( value );
}
else if ( 0 == strcmp( "myCurrentNumberOfPlayers", key ) )
{
server->num_players = atoi( value);
}
else
{
add_rule( server, key, value, NO_FLAGS );
}
}
else if ( 0 == strcmp( "Listing players", s ) )
{
// end of rules request
server->saved_data.pkt_index--;
mode++;
}
else if ( 0 == strcmp( "Exit confirmed.", s ) )
{
server->n_servers = mode;
return DONE_FORCE;
}
}
else if ( 1 == mode )
{
// Player info
if ( 0 == strncmp( s, "Team: ", 6 ) )
{
team = s + 6;
debug( 2, "Team: %s", team );
}
else if ( 4 == sscanf( s, "Slot: %d Role: %s Score: %d Name: %255[^\x0d\x0a]", &slot, role, &score, name ) )
{
// Player info
struct player *player = add_player( server, server->n_player_info );
if ( NULL != player )
{
player->flags |= PLAYER_FLAG_DO_NOT_FREE_TEAM;
player->name = strdup( name );
player->score = score;
player->team_name = team;
player->tribe_tag = strdup( role );
// Indicate if its a bot
player->type_flag = ( 0 == strcmp( name, "Computer: Balanced" ) ) ? 1 : 0;
}
debug( 2, "player %d, role %s, score %d, name %s", slot, role, score, name );
}
else if ( 3 == sscanf( s, "Slot: %d Role: Score: %d Name: %255[^\x0d\x0a]", &slot, &score, name ) )
{
// Player info
struct player *player = add_player( server, server->n_player_info );
if ( NULL != player )
{
player->flags |= PLAYER_FLAG_DO_NOT_FREE_TEAM;
player->name = strdup( name );
player->score = score;
player->team_name = team;
// Indicate if its a bot
player->type_flag = ( 0 == strcmp( name, "Computer: Balanced" ) ) ? 1 : 0;
}
debug( 2, "player %d, score %d, name %s", slot, score, name );
}
else if ( 0 == strcmp( "Exit confirmed.", s ) )
{
server->n_servers = mode;
return DONE_FORCE;
}
}
s += len;
if ( s + 1 < end )
{
s++; // next line
}
else
{
s = NULL;
}
}
server->n_servers = mode;
if ( 0 == server->saved_data.pkt_index )
{
server->map_name = strdup( "N/A" );
return DONE_FORCE;
}
return INPROGRESS;
}