📄 game.c
字号:
/* * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu) * Copyright (C) 1998,1999,2000 Ross Combs (rocombs@cs.nmsu.edu) * * 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. */#define GAME_INTERNAL_ACCESS#include "common/setup_before.h"#include <stdio.h>#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include "compat/strdup.h"#include "compat/strcasecmp.h"#include <errno.h>#include "compat/strerror.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#ifdef TIME_WITH_SYS_TIME# include <sys/time.h># include <time.h>#else# ifdef HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#include "compat/difftime.h"#ifdef HAVE_SYS_TYPES_H# include <sys/types.h>#endif#ifdef HAVE_ASSERT_H# include <assert.h>#endif#include "common/eventlog.h"#include "prefs.h"#include "connection.h"#include "account.h"#include "account_wrap.h"#include "ladder.h"#include "ladder_calc.h"#include "common/bnettime.h"#include "common/util.h"#include "common/elist.h"#include "common/tag.h"#include "common/addr.h"#include "common/xalloc.h"#include "realm.h"#include "watch.h"#include "game_conv.h"#include "game.h"#include "server.h"#include "compat/uint.h"#include "compat/rename.h"#include "common/setup_after.h"DECLARE_ELIST_INIT(gamelist_head);static int glist_length=0;static int totalcount=0;static void game_choose_host(t_game * game);static void game_destroy(t_game * game);static int game_report(t_game * game);static void game_choose_host(t_game * game){ unsigned int i; if (game->count<1) { eventlog(eventlog_level_error,__FUNCTION__,"game has had no connections?!"); return; } if (!game->connections) { eventlog(eventlog_level_error,__FUNCTION__,"game has NULL connections array"); return; } for (i=0; i<game->count; i++) if (game->connections[i]) { game->owner = game->connections[i]; game->addr = conn_get_game_addr(game->connections[i]); game->port = conn_get_game_port(game->connections[i]); return; } eventlog(eventlog_level_warn,__FUNCTION__,"no valid connections found");}extern char const * game_type_get_str(t_game_type type){ switch (type) { case game_type_none: return "NONE"; case game_type_melee: return "melee"; case game_type_topvbot: return "top vs bottom"; case game_type_ffa: return "free for all"; case game_type_oneonone: return "one on one"; case game_type_ctf: return "capture the flag"; case game_type_greed: return "greed"; case game_type_slaughter: return "slaughter"; case game_type_sdeath: return "sudden death"; case game_type_ladder: return "ladder"; case game_type_ironman: return "ironman"; case game_type_mapset: return "mapset"; case game_type_teammelee: return "team melee"; case game_type_teamffa: return "team free for all"; case game_type_teamctf: return "team capture the flag"; case game_type_pgl: return "PGL"; case game_type_diablo: return "Diablo"; case game_type_diablo2open: return "Diablo II (open)"; case game_type_diablo2closed: return "Diablo II (closed)"; case game_type_all: default: return "UNKNOWN"; }}extern char const * game_status_get_str(t_game_status status){ switch (status) { case game_status_started: return "started"; case game_status_full: return "full"; case game_status_open: return "open"; case game_status_done: return "done"; default: return "UNKNOWN"; }}extern char const * game_result_get_str(t_game_result result){ switch (result) { case game_result_none: return "NONE"; case game_result_win: return "WIN"; case game_result_loss: return "LOSS"; case game_result_draw: return "DRAW"; case game_result_disconnect: return "DISCONNECT"; case game_result_observer: return "OBSERVER"; default: return "UNKNOWN"; }}extern char const * game_option_get_str(t_game_option option){ switch (option) { case game_option_melee_normal: return "normal"; case game_option_ffa_normal: return "normal"; case game_option_oneonone_normal: return "normal"; case game_option_ctf_normal: return "normal"; case game_option_greed_10000: return "10000 minerals"; case game_option_greed_7500: return "7500 minerals"; case game_option_greed_5000: return "5000 minerals"; case game_option_greed_2500: return "2500 minerals"; case game_option_slaughter_60: return "60 minutes"; case game_option_slaughter_45: return "45 minutes"; case game_option_slaughter_30: return "30 minutes"; case game_option_slaughter_15: return "15 minutes"; case game_option_sdeath_normal: return "normal"; case game_option_ladder_countasloss: return "count as loss"; case game_option_ladder_nopenalty: return "no penalty"; case game_option_mapset_normal: return "normal"; case game_option_teammelee_4: return "4 teams"; case game_option_teammelee_3: return "3 teams"; case game_option_teammelee_2: return "2 teams"; case game_option_teamffa_4: return "4 teams"; case game_option_teamffa_3: return "3 teams"; case game_option_teamffa_2: return "2 teams"; case game_option_teamctf_4: return "4 teams"; case game_option_teamctf_3: return "3 teams"; case game_option_teamctf_2: return "2 teams"; case game_option_topvbot_7: return "7 vs all"; case game_option_topvbot_6: return "6 vs all"; case game_option_topvbot_5: return "5 vs all"; case game_option_topvbot_4: return "4 vs all"; case game_option_topvbot_3: return "3 vs all"; case game_option_topvbot_2: return "2 vs all"; case game_option_topvbot_1: return "1 vs all"; case game_option_none: return "none"; default: return "UNKNOWN"; }}extern char const * game_maptype_get_str(t_game_maptype maptype){ switch (maptype) { case game_maptype_selfmade: return "Self-Made"; case game_maptype_blizzard: return "Blizzard"; case game_maptype_ladder: return "Ladder"; case game_maptype_pgl: return "PGL"; case game_maptype_kbk: return "KBK"; case game_maptype_compusa: return "CompUSA"; default: return "Unknown"; }}extern char const * game_tileset_get_str(t_game_tileset tileset){ switch (tileset) { case game_tileset_badlands: return "Badlands"; case game_tileset_space: return "Space"; case game_tileset_installation: return "Installation"; case game_tileset_ashworld: return "Ash World"; case game_tileset_jungle: return "Jungle"; case game_tileset_desert: return "Desert"; case game_tileset_ice: return "Ice"; case game_tileset_twilight: return "Twilight"; default: return "Unknown"; }}extern char const * game_speed_get_str(t_game_speed speed){ switch (speed) { case game_speed_slowest: return "slowest"; case game_speed_slower: return "slower"; case game_speed_slow: return "slow"; case game_speed_normal: return "normal"; case game_speed_fast: return "fast"; case game_speed_faster: return "faster"; case game_speed_fastest: return "fastest"; default: return "unknown"; }}extern char const * game_difficulty_get_str(t_game_difficulty difficulty){ switch (difficulty) { case game_difficulty_normal: return "normal"; case game_difficulty_nightmare: return "nightmare"; case game_difficulty_hell: return "hell"; case game_difficulty_hardcore_normal: return "hardcore normal"; case game_difficulty_hardcore_nightmare: return "hardcore nightmare"; case game_difficulty_hardcore_hell: return "hardcore hell"; default: return "unknown"; }}extern t_game * game_create(char const * name, char const * pass, char const * info, t_game_type type, int startver, t_clienttag clienttag, unsigned long gameversion){ t_game * game; if (!name) { eventlog(eventlog_level_info,__FUNCTION__,"got NULL game name"); return NULL; } if (!pass) { eventlog(eventlog_level_info,__FUNCTION__,"got NULL game pass"); return NULL; } if (!info) { eventlog(eventlog_level_info,__FUNCTION__,"got NULL game info"); return NULL; } if (gamelist_find_game(name, clienttag, game_type_all)) { eventlog(eventlog_level_info,__FUNCTION__,"game \"%s\" not created because it already exists",name); return NULL; /* already have a game by that name */ } game = xmalloc(sizeof(t_game)); game->name = xstrdup(name); game->pass = xstrdup(pass); game->info = xstrdup(info); if (!(game->clienttag = clienttag)) { eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN clienttag"); xfree((void *)game->info); /* avoid warning */ xfree((void *)game->pass); /* avoid warning */ xfree((void *)game->name); /* avoid warning */ xfree(game); return NULL; } game->type = type; game->addr = 0; /* will be set by first player */ game->port = 0; /* will be set by first player */ game->version = gameversion; game->startver = startver; /* start packet version */ game->status = game_status_open; game->realm = 0; game->realmname = NULL; game->id = ++totalcount; game->mapname = NULL; game->ref = 0; game->count = 0; game->owner = NULL; game->connections = NULL; game->players = NULL; game->results = NULL; game->reported_results = NULL; game->report_heads = NULL; game->report_bodies = NULL; game->create_time = now; game->start_time = (time_t)0; game->lastaccess_time = now; game->option = game_option_none; game->maptype = game_maptype_none; game->tileset = game_tileset_none; game->speed = game_speed_none; game->mapsize_x = 0; game->mapsize_y = 0; game->maxplayers = 0; game->bad = 0; game->description = NULL; game->flag = strcmp(pass,"") ? game_flag_private : game_flag_none; game->difficulty = game_difficulty_none; game_parse_info(game,info); elist_add(&gamelist_head,&game->glist_link); glist_length++; eventlog(eventlog_level_info,__FUNCTION__,"game \"%s\" (pass \"%s\") type %hu(%s) startver %d created",name,pass,(unsigned short)type,game_type_get_str(game->type),startver); return game;}static void game_destroy(t_game * game){ unsigned int i; if (!game) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL game"); return; } elist_del(&game->glist_link); glist_length--; if (game->realmname) { realm_add_game_number(realmlist_find_realm(game->realmname),-1); } eventlog(eventlog_level_debug,__FUNCTION__,"game \"%s\" (count=%u ref=%u) removed from list...",game_get_name(game),game->count,game->ref); for (i=0; i<game->count; i++) { if (game->report_bodies && game->report_bodies[i]) xfree((void *)game->report_bodies[i]); /* avoid warning */ if (game->report_heads && game->report_heads[i]) xfree((void *)game->report_heads[i]); /* avoid warning */ if (game->reported_results && game->reported_results[i]) xfree((void *)game->reported_results[i]); } if (game->realmname) xfree((void *)game->realmname); /* avoid warining */ if (game->report_bodies) xfree((void *)game->report_bodies); /* avoid warning */ if (game->report_heads) xfree((void *)game->report_heads); /* avoid warning */ if (game->results) xfree((void *)game->results); /* avoid warning */ if (game->reported_results) xfree((void *)game->reported_results); if (game->connections) xfree((void *)game->connections); /* avoid warning */ if (game->players) xfree((void *)game->players); /* avoid warning */ if (game->mapname) xfree((void *)game->mapname); /* avoid warning */ if (game->description) xfree((void *)game->description); /* avoid warning */ xfree((void *)game->info); /* avoid warning */ xfree((void *)game->pass); /* avoid warning */ if (game->name) xfree((void *)game->name); /* avoid warning */ xfree((void *)game); /* avoid warning */ eventlog(eventlog_level_info,__FUNCTION__,"game deleted"); return;}static int game_evaluate_results(t_game * game){ unsigned int i,j; unsigned int wins, losses, draws, disconnects, reports; if (!game) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -