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 */ char tee_serverstatus[14] = { '\x20', '\0', '\0', '\0', '\0', '\0', '\xFF', '\xFF', '\xFF', '\xFF', 'g', 'i', 'e', 'f' }; { /* Teeworlds */ TEE_SERVER, /* id */ "TEE", /* type_prefix */ "tee", /* type_string */ "-tee", /* type_option */ "Teeworlds", /* game_name */ 0, /* master */ 35515, /* default_port */ 0, /* port_offset */ 0, /* flags */ "gametype", /* game_rule */ "TEE", /* template_var */ tee_serverstatus, /* status_packet */ sizeof(tee_serverstatus), /* 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_tee_player_info, /* display_player_func */ display_server_rules, /* display_rule_func */ raw_display_tee_player_info, /* display_raw_player_func */ raw_display_server_rules, /* display_raw_rule_func */ xml_display_tee_player_info, /* display_xml_player_func */ xml_display_server_rules, /* display_xml_rule_func */ send_tee_request_packet, /* status_query_func */ NULL, /* rule_query_func */ NULL, /* player_query_func */ deal_with_tee_packet, /* packet_func */ }, /* * qstat 2.11 * by Steve Jankowski * * Teeworlds protocol * Copyright 2008 ? Emiliano Leporati * * Licensed under the Artistic License, see LICENSE.txt for license terms * */ #include #include #include #include "debug.h" #include "qstat.h" #include "packet_manip.h" char tee_serverinfo[8] = { '\xFF', '\xFF', '\xFF', '\xFF', 'i', 'n', 'f', 'o' }; query_status_t send_tee_request_packet( struct qserver *server ) { return send_packet( server, server->type->status_packet, server->type->status_len ); } query_status_t deal_with_tee_packet( struct qserver *server, char *rawpkt, int pktlen ) { // skip unimplemented ack, crc, etc char *pkt = rawpkt + 6; char *tok = NULL, *version = NULL; int i; struct player* player; server->ping_total += time_delta(&packet_recv_time, &server->packet_time1); if (0 == memcmp( pkt, tee_serverinfo, 8)) { pkt += 8; // version version = strdup(pkt); pkt += strlen(pkt) + 1; // server name server->server_name = strdup(pkt); pkt += strlen(pkt) + 1; // map name server->map_name = strdup(pkt); pkt += strlen(pkt) + 1; // game type switch(atoi(pkt)) { case 0: add_rule( server, server->type->game_rule, "dm", NO_FLAGS); break; case 1: add_rule( server, server->type->game_rule, "tdm", NO_FLAGS); break; case 2: add_rule( server, server->type->game_rule, "ctf", NO_FLAGS); break; default: add_rule( server, server->type->game_rule, "unknown", NO_FLAGS); break; } pkt += strlen(pkt) + 1; pkt += strlen(pkt) + 1; pkt += strlen(pkt) + 1; // num players server->num_players = atoi(pkt); pkt += strlen(pkt) + 1; // max players server->max_players = atoi(pkt); pkt += strlen(pkt) + 1; // players for(i = 0; i < server->num_players; i++) { player = add_player( server, i ); player->name = strdup(pkt); pkt += strlen(pkt) + 1; player->score = atoi(pkt); pkt += strlen(pkt) + 1; } // version reprise server->protocol_version = 0; if (NULL == (tok = strtok(version, "."))) return -1; server->protocol_version |= (atoi(tok) & 0x000F) << 12; if (NULL == (tok = strtok(NULL, "."))) return -1; server->protocol_version |= (atoi(tok) & 0x000F) << 8; if (NULL == (tok = strtok(NULL, "."))) return -1; server->protocol_version |= (atoi(tok) & 0x00FF); free(version); return DONE_FORCE; } // unknown packet type return PKT_ERROR; }