📄 anongame.c
字号:
/* * Copyright (C) 2004 CreepLord (creeplord@pvpgn.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include "common/setup_before.h"#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif# ifdef HAVE_MEMORY_H# include <memory.h># endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef WIN32# include "compat/socket.h" /* is this needed */#endif#include "compat/strdup.h"#include "common/packet.h"#include "common/eventlog.h"#include "common/tag.h"#include "team.h"#include "account.h"#include "account_wrap.h"#include "connection.h"#include "common/queue.h"#include "prefs.h"#include "common/bn_type.h"#include "common/list.h"#include "common/addr.h"#include "common/xalloc.h"#include "versioncheck.h"#include "anongame.h"#include "tournament.h"#include "timer.h"#include "ladder.h"#include "server.h"#include "anongame_maplists.h"#include "anongame_gameresult.h"#include "common/trans.h"#include "common/setup_after.h"#define MAX_LEVEL 100/* [quetzal] 20020827 - this one get modified by anongame_queue player when there're enough * players and map has been chosen based on their preferences. otherwise its NULL */static char *mapname = NULL;static int players[ANONGAME_TYPES] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };static t_connection *player[ANONGAME_TYPES][ANONGAME_MAX_GAMECOUNT];/* [quetzal] 20020815 - queue to hold matching players */static t_list *matchlists[ANONGAME_TYPES][MAX_LEVEL];long average_anongame_search_time = 30;unsigned int anongame_search_count = 0;/**********************************************************************************/static t_connection *_connlist_find_connection_by_uid(int uid);static char const *_conn_get_versiontag(t_connection * c);static int _anongame_gametype_to_queue(int type, int gametype);static int _anongame_level_by_queue(t_connection * c, int queue);static char *_get_map_from_prefs(int queue, t_uint32 cur_prefs, t_clienttag clienttag);static unsigned int _anongame_get_gametype_tab(int queue);static int _anongame_totalplayers(int queue);static int _anongame_totalteams(int queue);static int _handle_anongame_search(t_connection * c, t_packet const *packet);static int _anongame_queue(t_connection * c, int queue, t_uint32 map_prefs);static int _anongame_compare_level(void const *a, void const *b);static int _anongame_order_queue(int queue);static int _anongame_match(t_connection * c, int queue);static int _anongame_search_found(int queue);/**********************************************************************************/static t_connection *_connlist_find_connection_by_uid(int uid){ return connlist_find_connection_by_account(accountlist_find_account_by_uid(uid));}static char const *_conn_get_versiontag(t_connection * c){ return versioncheck_get_versiontag(conn_get_versioncheck(c));}/**********/static char const *_anongame_queue_to_string(int queue){ switch (queue) { case ANONGAME_TYPE_1V1: return "PG 1v1"; case ANONGAME_TYPE_2V2: return "PG 2v2"; case ANONGAME_TYPE_3V3: return "PG 3v3"; case ANONGAME_TYPE_4V4: return "PG 4v4"; case ANONGAME_TYPE_SMALL_FFA: return "PG SFFA"; case ANONGAME_TYPE_AT_2V2: return "AT 2v2"; case ANONGAME_TYPE_TEAM_FFA: return "AT TFFA"; case ANONGAME_TYPE_AT_3V3: return "AT 3v3"; case ANONGAME_TYPE_AT_4V4: return "AT 4v4"; case ANONGAME_TYPE_TY: return "TOURNEY"; case ANONGAME_TYPE_5V5: return "PG 5v5"; case ANONGAME_TYPE_6V6: return "PG 6v6"; case ANONGAME_TYPE_2V2V2: return "PG 2v2v2"; case ANONGAME_TYPE_3V3V3: return "PG 3v3v3"; case ANONGAME_TYPE_4V4V4: return "PG 4v4v4"; case ANONGAME_TYPE_2V2V2V2: return "PG 2v2v2v2"; case ANONGAME_TYPE_3V3V3V3: return "PG 3v3v3v3"; case ANONGAME_TYPE_AT_2V2V2: return "AT 2v2v2"; default: eventlog(eventlog_level_error, __FUNCTION__, "invalid queue number %d", queue); return "error"; }}static int _anongame_gametype_to_queue(int type, int gametype){ switch (type) { case 0: /* PG */ switch (gametype) { case 0: return ANONGAME_TYPE_1V1; case 1: return ANONGAME_TYPE_2V2; case 2: return ANONGAME_TYPE_3V3; case 3: return ANONGAME_TYPE_4V4; case 4: return ANONGAME_TYPE_SMALL_FFA; case 5: return ANONGAME_TYPE_5V5; case 6: return ANONGAME_TYPE_6V6; case 7: return ANONGAME_TYPE_2V2V2; case 8: return ANONGAME_TYPE_3V3V3; case 9: return ANONGAME_TYPE_4V4V4; case 10: return ANONGAME_TYPE_2V2V2V2; case 11: return ANONGAME_TYPE_3V3V3V3; default: eventlog(eventlog_level_error, __FUNCTION__, "invalid PG game type: %d", gametype); return -1; } case 1: /* AT */ switch (gametype) { case 0: return ANONGAME_TYPE_AT_2V2; case 2: return ANONGAME_TYPE_AT_3V3; case 3: return ANONGAME_TYPE_AT_4V4; case 4: return ANONGAME_TYPE_AT_2V2V2; default: eventlog(eventlog_level_error, __FUNCTION__, "invalid AT game type: %d", gametype); return -1; } case 2: /* TY */ return ANONGAME_TYPE_TY; default: eventlog(eventlog_level_error, __FUNCTION__, "invalid type: %d", type); return -1; }}static int _anongame_level_by_queue(t_connection * c, int queue){ t_clienttag ct = conn_get_clienttag(c); switch (queue) { case ANONGAME_TYPE_1V1: return account_get_ladder_level(conn_get_account(c), ct, ladder_id_solo); case ANONGAME_TYPE_2V2: case ANONGAME_TYPE_3V3: case ANONGAME_TYPE_4V4: case ANONGAME_TYPE_5V5: case ANONGAME_TYPE_6V6: case ANONGAME_TYPE_2V2V2: case ANONGAME_TYPE_3V3V3: case ANONGAME_TYPE_4V4V4: case ANONGAME_TYPE_2V2V2V2: case ANONGAME_TYPE_3V3V3V3: return account_get_ladder_level(conn_get_account(c), ct, ladder_id_ffa); case ANONGAME_TYPE_SMALL_FFA: case ANONGAME_TYPE_TEAM_FFA: return account_get_ladder_level(conn_get_account(c), ct, ladder_id_ffa); case ANONGAME_TYPE_AT_2V2: case ANONGAME_TYPE_AT_3V3: case ANONGAME_TYPE_AT_4V4: case ANONGAME_TYPE_AT_2V2V2: return 0; case ANONGAME_TYPE_TY: /* set to ((wins * 3) + ties - losses) ie. prelim score */ return tournament_get_player_score(conn_get_account(c)); default: eventlog(eventlog_level_error, __FUNCTION__, "unknown queue: %d", queue); return -1; }}static char *_get_map_from_prefs(int queue, t_uint32 cur_prefs, t_clienttag clienttag){ int i, j = 0; char *default_map, *selected; char *res_maps[32]; if (clienttag == CLIENTTAG_WARCRAFT3_UINT) default_map = "Maps\\(8)PlainsOfSnow.w3m"; else if (clienttag == CLIENTTAG_WAR3XP_UINT) default_map = "Maps\\(8)PlainsOfSnow.w3m"; else { eventlog(eventlog_level_error, __FUNCTION__, "invalid clienttag : %s", clienttag); return "Maps\\(8)PlainsOfSnow.w3m"; } for (i = 0; i < 32; i++) res_maps[i] = NULL; for (i = 0; i < 32; i++) { if (cur_prefs & 1) res_maps[j++] = maplists_get_map(queue, clienttag, i + 1); cur_prefs >>= 1; } i = rand() % j; if (res_maps[i]) selected = res_maps[i]; else selected = default_map; eventlog(eventlog_level_trace, __FUNCTION__, "got map %s from prefs", selected); return selected;}static unsigned int _anongame_get_gametype_tab(int queue){ /* dizzy: this changed in 1.05 */ switch (queue) { case ANONGAME_TYPE_1V1: return SERVER_ANONGAME_SOLO_STR; case ANONGAME_TYPE_2V2: case ANONGAME_TYPE_3V3: case ANONGAME_TYPE_4V4: case ANONGAME_TYPE_5V5: case ANONGAME_TYPE_6V6: case ANONGAME_TYPE_2V2V2: case ANONGAME_TYPE_3V3V3: case ANONGAME_TYPE_4V4V4: case ANONGAME_TYPE_2V2V2V2: case ANONGAME_TYPE_3V3V3V3: return SERVER_ANONGAME_TEAM_STR; case ANONGAME_TYPE_SMALL_FFA: return SERVER_ANONGAME_SFFA_STR; case ANONGAME_TYPE_TEAM_FFA: return 0; /* Team FFA is no longer supported */ case ANONGAME_TYPE_AT_2V2: return SERVER_ANONGAME_AT2v2_STR; case ANONGAME_TYPE_AT_3V3: return SERVER_ANONGAME_AT3v3_STR; case ANONGAME_TYPE_AT_4V4: return SERVER_ANONGAME_AT4v4_STR; case ANONGAME_TYPE_AT_2V2V2: return SERVER_ANONGAME_AT2v2_STR; /* fixme */ case ANONGAME_TYPE_TY: return SERVER_ANONGAME_TY_STR; default: eventlog(eventlog_level_error, __FUNCTION__, "invalid queue (%d)", queue); return 0; }}static int _anongame_totalplayers(int queue){ switch (queue) { case ANONGAME_TYPE_1V1: return 2; case ANONGAME_TYPE_2V2: case ANONGAME_TYPE_AT_2V2: case ANONGAME_TYPE_SMALL_FFA: /* fixme: total players not always 4 */ return 4; case ANONGAME_TYPE_3V3: case ANONGAME_TYPE_AT_3V3: case ANONGAME_TYPE_2V2V2: case ANONGAME_TYPE_AT_2V2V2: return 6; case ANONGAME_TYPE_4V4: case ANONGAME_TYPE_AT_4V4: case ANONGAME_TYPE_TEAM_FFA: case ANONGAME_TYPE_2V2V2V2: return 8; case ANONGAME_TYPE_3V3V3: return 9; case ANONGAME_TYPE_5V5: return 10; case ANONGAME_TYPE_6V6: case ANONGAME_TYPE_4V4V4: case ANONGAME_TYPE_3V3V3V3: return 12; case ANONGAME_TYPE_TY: return tournament_get_totalplayers(); default: eventlog(eventlog_level_error, __FUNCTION__, "unknown queue: %d", queue); return 0; }}static int _anongame_totalteams(int queue){/* dont forget to change this if you make some game type with more teams */#define ANONGAME_MAX_TEAMS 4 switch (queue) { case ANONGAME_TYPE_1V1: case ANONGAME_TYPE_SMALL_FFA: return 0; case ANONGAME_TYPE_2V2: case ANONGAME_TYPE_3V3: case ANONGAME_TYPE_4V4: case ANONGAME_TYPE_5V5: case ANONGAME_TYPE_6V6: case ANONGAME_TYPE_AT_2V2: case ANONGAME_TYPE_AT_3V3: case ANONGAME_TYPE_AT_4V4: return 2; case ANONGAME_TYPE_2V2V2: case ANONGAME_TYPE_3V3V3: case ANONGAME_TYPE_4V4V4: case ANONGAME_TYPE_AT_2V2V2: return 3; case ANONGAME_TYPE_TEAM_FFA: /* not even used */ case ANONGAME_TYPE_2V2V2V2: case ANONGAME_TYPE_3V3V3V3: return 4; case ANONGAME_TYPE_TY: return 2; /* fixme: does not support 2v2v2 - tournament_get_totalteams() */ default: eventlog(eventlog_level_error, __FUNCTION__, "unknown queue: %d", queue); return 0; }}/**********/static int _handle_anongame_search(t_connection * c, t_packet const *packet){ int i, j, temp, set = 1; t_packet *rpacket; t_connection *tc[6]; t_anongame *a, *ta; t_uint8 teamsize = 0; t_uint8 option = bn_byte_get(packet->u.client_findanongame.option); if (!(a = conn_get_anongame(c))) { if (!(a = conn_create_anongame(c))) { eventlog(eventlog_level_error, __FUNCTION__, "[%d] conn_create_anongame failed", conn_get_socket(c)); return -1; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -