mirror of
https://github.com/tribufu/node-gamedig
synced 2026-05-06 15:17:36 +00:00
Add a ton of reference
This commit is contained in:
parent
473d9544b1
commit
09d9b87ad6
22 changed files with 5115 additions and 4 deletions
455
reference/tribes2/qstat.txt
Normal file
455
reference/tribes2/qstat.txt
Normal file
|
|
@ -0,0 +1,455 @@
|
|||
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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* TRIBES 2 */
|
||||
#define TRIBES2_QUERY_GAME_TYPES 2
|
||||
#define TRIBES2_QUERY_MASTER 6
|
||||
#define TRIBES2_QUERY_PING 14
|
||||
#define TRIBES2_QUERY_INFO 18
|
||||
#define TRIBES2_RESPONSE_GAME_TYPES 4
|
||||
#define TRIBES2_RESPONSE_MASTER 8
|
||||
#define TRIBES2_RESPONSE_PING 16
|
||||
#define TRIBES2_RESPONSE_INFO 20
|
||||
|
||||
#define TRIBES2_NO_COMPRESS 2
|
||||
#define TRIBES2_DEFAULT_PACKET_INDEX 255
|
||||
#define TRIBES2_STATUS_DEDICATED (1<<0)
|
||||
#define TRIBES2_STATUS_PASSWORD (1<<1)
|
||||
#define TRIBES2_STATUS_LINUX (1<<2)
|
||||
#define TRIBES2_STATUS_TOURNAMENT (1<<3)
|
||||
#define TRIBES2_STATUS_NOALIAS (1<<4)
|
||||
#define TRIBES2_STATUS_TEAMDAMAGE (1<<5)
|
||||
#define TRIBES2_STATUS_TOURNAMENT_VER3 (1<<6)
|
||||
#define TRIBES2_STATUS_NOALIAS_VER3 (1<<7)
|
||||
char tribes2_game_types_request[] = { TRIBES2_QUERY_GAME_TYPES, 0, 1,2,3,4 };
|
||||
char tribes2_ping[] = { TRIBES2_QUERY_PING, TRIBES2_NO_COMPRESS, 1,2,3,4 };
|
||||
char tribes2_info[] = { TRIBES2_QUERY_INFO, TRIBES2_NO_COMPRESS, 1,2,3,4 };
|
||||
unsigned char tribes2_masterquery[] = {
|
||||
TRIBES2_QUERY_MASTER, 128, /* <= build 22228, this was 0 */
|
||||
11,12,13,14,
|
||||
255,
|
||||
3, 'a', 'n', 'y',
|
||||
3, 'a', 'n', 'y',
|
||||
0, 255, /* min/max players */
|
||||
0xff, 0xff, 0xff, 0xff, /* region mask */
|
||||
0, 0, 0, 0, /* build version */
|
||||
0, /* status */
|
||||
255, /* max bots */
|
||||
0, 0, /* min cpu */
|
||||
0 /* # buddies */
|
||||
};
|
||||
#define TRIBES2_ID_OFFSET 2
|
||||
|
||||
|
||||
|
||||
|
||||
{
|
||||
/* TRIBES 2 */
|
||||
TRIBES2_SERVER, /* id */
|
||||
"T2S", /* type_prefix */
|
||||
"t2s", /* type_string */
|
||||
"-t2s", /* type_option */
|
||||
"Tribes 2", /* game_name */
|
||||
0, /* master */
|
||||
TRIBES2_DEFAULT_PORT, /* default_port */
|
||||
0, /* port_offset */
|
||||
0, /* flags */
|
||||
"game", /* game_rule */
|
||||
"TRIBES2", /* template_var */
|
||||
(char*) &tribes2_ping, /* status_packet */
|
||||
sizeof( tribes2_ping), /* status_len */
|
||||
(char*) &tribes2_info, /* player_packet */
|
||||
sizeof( tribes2_info), /* player_len */
|
||||
(char*) NULL, /* rule_packet */
|
||||
0, /* rule_len */
|
||||
NULL, /* master_packet */
|
||||
0, /* master_len */
|
||||
NULL, /* master_protocol */
|
||||
NULL, /* master_query */
|
||||
display_tribes2_player_info, /* display_player_func */
|
||||
display_server_rules, /* display_rule_func */
|
||||
raw_display_tribes2_player_info, /* display_raw_player_func */
|
||||
raw_display_server_rules, /* display_raw_rule_func */
|
||||
xml_display_tribes2_player_info, /* display_xml_player_func */
|
||||
xml_display_server_rules, /* display_xml_rule_func */
|
||||
send_tribes2_request_packet, /* status_query_func */
|
||||
NULL, /* rule_query_func */
|
||||
NULL, /* player_query_func */
|
||||
deal_with_tribes2_packet, /* packet_func */
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
query_status_t send_tribes2_request_packet(struct qserver *server)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (server->flags &FLAG_BROADCAST && server->server_name == NULL)
|
||||
{
|
||||
rc = send_broadcast(server, server->type->status_packet, server->type->status_len);
|
||||
}
|
||||
else if (server->server_name == NULL)
|
||||
{
|
||||
rc = send(server->fd, server->type->status_packet, server->type->status_len, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = send(server->fd, server->type->player_packet, server->type->player_len, 0);
|
||||
}
|
||||
|
||||
if (rc == SOCKET_ERROR)
|
||||
{
|
||||
return send_error( server, rc );
|
||||
}
|
||||
|
||||
register_send(server);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void get_tribes2_player_type(struct player *player)
|
||||
{
|
||||
char *name = player->name;
|
||||
for (; *name; name++)
|
||||
{
|
||||
switch (*name)
|
||||
{
|
||||
case 0x8:
|
||||
player->type_flag = PLAYER_TYPE_NORMAL;
|
||||
continue;
|
||||
case 0xc:
|
||||
player->type_flag = PLAYER_TYPE_ALIAS;
|
||||
continue;
|
||||
case 0xe:
|
||||
player->type_flag = PLAYER_TYPE_BOT;
|
||||
continue;
|
||||
case 0xb:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
name++;
|
||||
if (isprint(*name))
|
||||
{
|
||||
char *n = name;
|
||||
for (; isprint(*n); n++)
|
||||
;
|
||||
player->tribe_tag = strndup(name, n - name);
|
||||
name = n;
|
||||
}
|
||||
if (! *name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query_status_t deal_with_tribes2_packet(struct qserver *server, char *pkt, int pktlen)
|
||||
{
|
||||
char str[256], *pktstart = pkt, *term, *start;
|
||||
unsigned int minimum_net_protocol, build_version, i, t, len, s, status;
|
||||
unsigned int net_protocol;
|
||||
unsigned short cpu_speed;
|
||||
int n_teams = 0, n_players;
|
||||
struct player **teams = NULL, *player;
|
||||
struct player **last_player = &server->players;
|
||||
int query_version;
|
||||
|
||||
debug( 2, "deal_with_tribes2_packet %p, %d", server, pktlen );
|
||||
|
||||
pkt[pktlen] = '\0';
|
||||
|
||||
if (server->server_name == NULL)
|
||||
{
|
||||
server->ping_total += time_delta(&packet_recv_time, &server->packet_time1);
|
||||
}
|
||||
/*
|
||||
else
|
||||
gettimeofday( &server->packet_time1, NULL);
|
||||
*/
|
||||
|
||||
if (pkt[0] == TRIBES2_RESPONSE_PING)
|
||||
{
|
||||
if (pkt[6] < 4 || pkt[6] > 12 || strncmp(pkt + 7, "VER", 3) != 0)
|
||||
{
|
||||
return PKT_ERROR;
|
||||
}
|
||||
|
||||
strncpy(str, pkt + 10, pkt[6] - 3);
|
||||
str[pkt[6] - 3] = '\0';
|
||||
query_version = atoi(str);
|
||||
add_nrule(server, "queryversion", pkt + 7, pkt[6]);
|
||||
pkt += 7+pkt[6];
|
||||
|
||||
server->protocol_version = query_version;
|
||||
if (query_version != 3 && query_version != 5)
|
||||
{
|
||||
server->server_name = strdup("Unknown query version");
|
||||
return PKT_ERROR;
|
||||
}
|
||||
|
||||
if (query_version == 5)
|
||||
{
|
||||
net_protocol = swap_long_from_little(pkt);
|
||||
sprintf(str, "%u", net_protocol);
|
||||
add_rule(server, "net_protocol", str, NO_FLAGS);
|
||||
pkt += 4;
|
||||
}
|
||||
minimum_net_protocol = swap_long_from_little(pkt);
|
||||
sprintf(str, "%u", minimum_net_protocol);
|
||||
add_rule(server, "minimum_net_protocol", str, NO_FLAGS);
|
||||
pkt += 4;
|
||||
build_version = swap_long_from_little(pkt);
|
||||
sprintf(str, "%u", build_version);
|
||||
add_rule(server, "build_version", str, NO_FLAGS);
|
||||
pkt += 4;
|
||||
|
||||
server->server_name = strndup(pkt + 1, *(unsigned char*)(pkt));
|
||||
|
||||
/* Always send the player request because the ping packet
|
||||
* contains very little information */
|
||||
send_player_request_packet(server);
|
||||
return 0;
|
||||
}
|
||||
else if (pkt[0] != TRIBES2_RESPONSE_INFO)
|
||||
{
|
||||
return PKT_ERROR;
|
||||
}
|
||||
|
||||
pkt += 6;
|
||||
for (i = 0; i < *(unsigned char*)pkt; i++)
|
||||
if (!isprint(pkt[i + 1]))
|
||||
{
|
||||
return PKT_ERROR;
|
||||
}
|
||||
add_nrule(server, server->type->game_rule, pkt + 1, *(unsigned char*)pkt);
|
||||
server->game = strndup(pkt + 1, *(unsigned char*)pkt);
|
||||
pkt += *pkt + 1;
|
||||
add_nrule(server, "mission", pkt + 1, *(unsigned char*)pkt);
|
||||
pkt += *pkt + 1;
|
||||
server->map_name = strndup(pkt + 1, *(unsigned char*)pkt);
|
||||
pkt += *pkt + 1;
|
||||
|
||||
status = *(unsigned char*)pkt;
|
||||
sprintf(str, "%u", status);
|
||||
add_rule(server, "status", str, NO_FLAGS);
|
||||
if (status &TRIBES2_STATUS_DEDICATED)
|
||||
{
|
||||
add_rule(server, "dedicated", "1", NO_FLAGS);
|
||||
}
|
||||
if (status &TRIBES2_STATUS_PASSWORD)
|
||||
{
|
||||
add_rule(server, "password", "1", NO_FLAGS);
|
||||
}
|
||||
if (status &TRIBES2_STATUS_LINUX)
|
||||
{
|
||||
add_rule(server, "linux", "1", NO_FLAGS);
|
||||
}
|
||||
if (status &TRIBES2_STATUS_TEAMDAMAGE)
|
||||
{
|
||||
add_rule(server, "teamdamage", "1", NO_FLAGS);
|
||||
}
|
||||
if (server->protocol_version == 3)
|
||||
{
|
||||
if (status &TRIBES2_STATUS_TOURNAMENT_VER3)
|
||||
{
|
||||
add_rule(server, "tournament", "1", NO_FLAGS);
|
||||
}
|
||||
if (status &TRIBES2_STATUS_NOALIAS_VER3)
|
||||
{
|
||||
add_rule(server, "no_aliases", "1", NO_FLAGS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (status &TRIBES2_STATUS_TOURNAMENT)
|
||||
{
|
||||
add_rule(server, "tournament", "1", NO_FLAGS);
|
||||
}
|
||||
if (status &TRIBES2_STATUS_NOALIAS)
|
||||
{
|
||||
add_rule(server, "no_aliases", "1", NO_FLAGS);
|
||||
}
|
||||
}
|
||||
pkt++;
|
||||
server->num_players = *(unsigned char*)pkt;
|
||||
pkt++;
|
||||
server->max_players = *(unsigned char*)pkt;
|
||||
pkt++;
|
||||
sprintf(str, "%u", *(unsigned char*)pkt);
|
||||
add_rule(server, "bot_count", str, NO_FLAGS);
|
||||
pkt++;
|
||||
cpu_speed = swap_short_from_little(pkt);
|
||||
sprintf(str, "%hu", cpu_speed);
|
||||
add_rule(server, "cpu_speed", str, NO_FLAGS);
|
||||
pkt += 2;
|
||||
|
||||
if (strcmp(server->server_name, "VER3") == 0)
|
||||
{
|
||||
free(server->server_name);
|
||||
server->server_name = strndup(pkt + 1, *(unsigned char*)pkt);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_nrule(server, "info", pkt + 1, *(unsigned char*)pkt);
|
||||
}
|
||||
|
||||
pkt += *(unsigned char*)pkt + 1;
|
||||
len = swap_short_from_little(pkt);
|
||||
pkt += 2;
|
||||
start = pkt;
|
||||
if (len + (pkt - pktstart) > pktlen)
|
||||
{
|
||||
len -= (len + (pkt - pktstart)) - pktlen;
|
||||
}
|
||||
|
||||
if (len == 0 || pkt - pktstart >= pktlen)
|
||||
{
|
||||
goto info_done;
|
||||
}
|
||||
|
||||
term = strchr(pkt, 0xa);
|
||||
if (!term)
|
||||
{
|
||||
goto info_done;
|
||||
}
|
||||
*term = '\0';
|
||||
n_teams = atoi(pkt);
|
||||
sprintf(str, "%d", n_teams);
|
||||
add_rule(server, "numteams", str, NO_FLAGS);
|
||||
pkt = term + 1;
|
||||
|
||||
if (pkt - pktstart >= pktlen)
|
||||
{
|
||||
goto info_done;
|
||||
}
|
||||
|
||||
teams = (struct player **)calloc(1, sizeof(struct player*) * n_teams);
|
||||
for (t = 0; t < n_teams; t++)
|
||||
{
|
||||
teams[t] = (struct player*)calloc(1, sizeof(struct player));
|
||||
teams[t]->number = TRIBES_TEAM;
|
||||
teams[t]->team = t;
|
||||
/* team name */
|
||||
term = strchr(pkt, 0x9);
|
||||
if (!term)
|
||||
{
|
||||
n_teams = t;
|
||||
goto info_done;
|
||||
} teams[t]->name = strndup(pkt, term - pkt);
|
||||
pkt = term + 1;
|
||||
term = strchr(pkt, 0xa);
|
||||
if (!term)
|
||||
{
|
||||
n_teams = t;
|
||||
goto info_done;
|
||||
}
|
||||
*term = '\0';
|
||||
teams[t]->frags = atoi(pkt);
|
||||
pkt = term + 1;
|
||||
if (pkt - pktstart >= pktlen)
|
||||
{
|
||||
goto info_done;
|
||||
}
|
||||
}
|
||||
|
||||
term = strchr(pkt, 0xa);
|
||||
if (!term || term - start >= len)
|
||||
{
|
||||
goto info_done;
|
||||
}
|
||||
*term = '\0';
|
||||
n_players = atoi(pkt);
|
||||
pkt = term + 1;
|
||||
|
||||
for (i = 0; i < n_players && pkt - start < len; i++)
|
||||
{
|
||||
pkt++; /* skip first byte (0x10) */
|
||||
if (pkt - start >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
player = (struct player*)calloc(1, sizeof(struct player));
|
||||
term = strchr(pkt, 0x11);
|
||||
if (!term || term - start >= len)
|
||||
{
|
||||
free(player);
|
||||
break;
|
||||
} player->name = strndup(pkt, term - pkt);
|
||||
get_tribes2_player_type(player);
|
||||
pkt = term + 1;
|
||||
pkt++; /* skip 0x9 */
|
||||
if (pkt - start >= len)
|
||||
{
|
||||
break;
|
||||
}
|
||||
term = strchr(pkt, 0x9);
|
||||
if (!term || term - start >= len)
|
||||
{
|
||||
free(player->name);
|
||||
free(player);
|
||||
break;
|
||||
}
|
||||
for (t = 0; t < n_teams; t++)
|
||||
{
|
||||
if (term - pkt == strlen(teams[t]->name) && strncmp(pkt, teams[t]->name, term - pkt) == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t == n_teams)
|
||||
{
|
||||
player->team = - 1;
|
||||
player->team_name = "Unassigned";
|
||||
}
|
||||
else
|
||||
{
|
||||
player->team = t;
|
||||
player->team_name = teams[t]->name;
|
||||
}
|
||||
player->flags |= PLAYER_FLAG_DO_NOT_FREE_TEAM;
|
||||
pkt = term + 1;
|
||||
for (s = 0; *pkt != 0xa && pkt - start < len; pkt++)
|
||||
{
|
||||
str[s++] = *pkt;
|
||||
}
|
||||
str[s] = '\0';
|
||||
player->frags = atoi(str);
|
||||
if (*pkt == 0xa)
|
||||
{
|
||||
pkt++;
|
||||
}
|
||||
|
||||
*last_player = player;
|
||||
last_player = &player->next;
|
||||
}
|
||||
|
||||
info_done:
|
||||
for (t = n_teams; t;)
|
||||
{
|
||||
t--;
|
||||
teams[t]->next = server->players;
|
||||
server->players = teams[t];
|
||||
}
|
||||
if (teams)
|
||||
{
|
||||
free(teams);
|
||||
}
|
||||
|
||||
return DONE_FORCE;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue