mirror of
https://github.com/gamedig/node-gamedig.git
synced 2024-11-16 16:58:32 +01:00
241 lines
6 KiB
Text
241 lines
6 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;
|
|
}
|
|
|