⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.c

📁 打魔兽战网的都知道他是什么
💻 C
📖 第 1 页 / 共 4 页
字号:
      return -1;  }  if (!game->results)  {      eventlog(eventlog_level_error,__FUNCTION__,"results array is NULL");      return -1;  }  if (!game->reported_results)  {      eventlog(eventlog_level_error,__FUNCTION__,"reported_results array is NULL");      return -1;  }  for (i=0;i<game->count;i++)  {    wins = losses = draws = disconnects = reports = 0;    for (j=0;j<game->count;j++)    {      if (game->reported_results[j])      {        switch (game->reported_results[j][i])	{	  case game_result_win:	    wins++;	    reports++;	    break;	  case game_result_loss:	    losses++;	    reports++;	    break;	  case game_result_draw:	    draws++;	    reports++;	    break;	  case game_result_disconnect:	    disconnects++;	    reports++;	    break;	  default:	    break;	}      }    }    eventlog(eventlog_level_debug,__FUNCTION__,"wins: %u losses: %u draws: %u disconnects: %u",wins,losses,draws,disconnects);        //now decide what result we give    if (!(reports)) // no results at all - game canceled before starting    {      game->results[i] = game_result_none;      eventlog(eventlog_level_debug,__FUNCTION__,"deciding to give \"none\" to player %d",i);    }    else if ((disconnects>=draws) && (disconnects>=losses) && (disconnects>=wins))    {      game->results[i] = game_result_disconnect; //consider disconnects the worst case...      eventlog(eventlog_level_debug,__FUNCTION__,"deciding to give \"disconnect\" to player %d",i);    }    else if ((losses>=wins) && (losses>=draws))    {      game->results[i]=game_result_loss;         //losses are also bad...      eventlog(eventlog_level_debug,__FUNCTION__,"deciding to give \"loss\" to player %d",i);    }    else if ((draws>=wins))    {      game->results[i]=game_result_draw;      eventlog(eventlog_level_debug,__FUNCTION__,"deciding to give \"draw\" to player %d",i);    }    else if (wins)    {      game->results[i]=game_result_win;      eventlog(eventlog_level_debug,__FUNCTION__,"deciding to give \"win\" to player %d",i);    }  }  return 0;}static int game_match_type(t_game_type type,const char *gametypes){    char *p, *q;    int res;    if (!gametypes || !gametypes[0]) return 0;    gametypes = p = xstrdup(gametypes);    res = 0;    do {	q = strchr(p,',');	if (q) *q = '\0';	if (!strcasecmp(p,"topvbot")) {	    if (type == game_type_topvbot) { res = 1; break; }	} else if (!strcasecmp(p,"melee")) {	    if (type == game_type_melee) { res = 1; break; }	} else if (!strcasecmp(p,"ffa")) {	    if (type == game_type_ffa) { res = 1; break; }	} else if (!strcasecmp(p,"oneonone")) {	    if (type == game_type_oneonone) { res = 1; break; }	}	if (q) p = q + 1;    } while(q);    free((void*)gametypes);    return res;}static int game_report(t_game * game){    FILE *          fp;    char *          realname;    char *          tempname;    unsigned int    i;    unsigned int    realcount;    t_ladder_info * ladder_info=NULL;    int             discisloss;    char            clienttag_str[5];        if (!game)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");	return -1;    }    if (!game->clienttag)    {	eventlog(eventlog_level_error,__FUNCTION__,"got UNKNOWN clienttag");	return -1;    }    if (!game->players)    {	eventlog(eventlog_level_error,__FUNCTION__,"player array is NULL");	return -1;    }    if (!game->reported_results)    {        eventlog(eventlog_level_error,__FUNCTION__,"reported_results array is NULL");	return -1;    }    if (!game->results)    {	eventlog(eventlog_level_error,__FUNCTION__,"results array is NULL");	return -1;    }        if (prefs_get_discisloss()==1 || game->option==game_option_ladder_countasloss)	discisloss = 1;    else	discisloss = 0;    if (game->clienttag==CLIENTTAG_WARCRAFT3_UINT || game->clienttag==CLIENTTAG_WAR3XP_UINT)    // war3 game reporting is done elsewhere, so we can skip this function	    return 0;        if (game->clienttag==CLIENTTAG_DIABLOSHR_UINT ||        game->clienttag==CLIENTTAG_DIABLORTL_UINT ||        game->clienttag==CLIENTTAG_DIABLO2ST_UINT ||        game->clienttag==CLIENTTAG_DIABLO2DV_UINT ||        game->clienttag==CLIENTTAG_DIABLO2XP_UINT)    {      if (prefs_get_report_diablo_games() == 1)	/* diablo games have transient players and no reported winners/losers */	realcount = 0;      else      {	eventlog(eventlog_level_info,__FUNCTION__,"diablo gamereport disabled: ignoring game");	return 0;      }    }    else    {        game_evaluate_results(game); // evaluate results from the reported results	/* "compact" the game; move all the real players to the top... */	realcount = 0;	for (i=0; i<game->count; i++)	{	    if (!game->players[i])	    {		eventlog(eventlog_level_error,__FUNCTION__,"player slot %u has NULL account",i);		continue;	    }	    	    if (game->results[i]!=game_result_none)	    {		game->players[realcount]       = game->players[i];		game->results[realcount]       = game->results[i];		game->report_heads[realcount]  = game->report_heads[i];		game->report_bodies[realcount] = game->report_bodies[i];		realcount++;	    }	}		/* then nuke duplicate players after the real players */	for (i=realcount; i<game->count; i++)	{	    game->players[i]          = NULL;	    game->results[i]          = game_result_none;	    game->report_heads[i]     = NULL;	    game->report_bodies[i]    = NULL;	}		if (realcount<1)	{	    eventlog(eventlog_level_info,__FUNCTION__,"ignoring game");	    return -1;	}    }    eventlog(eventlog_level_debug,__FUNCTION__,"realcount=%d count=%u",realcount,game->count);    if (realcount>=1 && !game->bad)    {	if (game_is_ladder(game)	    )	{	    t_ladder_id id;	    if (game_get_type(game)==game_type_ironman)		id = ladder_id_ironman;	    else		id = ladder_id_normal;	    for (i=0; i<realcount; i++)	    {		eventlog(eventlog_level_debug,__FUNCTION__,"realplayer %u result=%u",i+1,(unsigned int)game->results[i]);				ladder_init_account(game->players[i],game->clienttag,id);				switch (game->results[i])		{		case game_result_win:		    account_inc_ladder_wins(game->players[i],game->clienttag,id);		    account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_win));		    break;		case game_result_loss:		    account_inc_ladder_losses(game->players[i],game->clienttag,id);		    account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_loss));		    break;		case game_result_draw:		    account_inc_ladder_draws(game->players[i],game->clienttag,id);		    account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_draw));		    break;		case game_result_disconnect:		    if (discisloss)		    {			account_inc_ladder_losses(game->players[i],game->clienttag,id);			account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_loss));		    }		    else		    {/* FIXME: do the first disconnect only stuff like below */			account_inc_ladder_disconnects(game->players[i],game->clienttag,id);			account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_disconnect));		    }		    break;		default:		    eventlog(eventlog_level_error,__FUNCTION__,"bad ladder game realplayer results[%u] = %u",i,game->results[i]);		    account_inc_ladder_disconnects(game->players[i],game->clienttag,id);		    account_set_ladder_last_result(game->players[i],game->clienttag,id,game_result_get_str(game_result_disconnect));		}		account_set_ladder_last_time(game->players[i],game->clienttag,id,bnettime());	    }	    ladder_info = xmalloc(sizeof(t_ladder_info)*realcount);	    if (ladder_update(game->clienttag,id,		realcount,game->players,game->results,ladder_info,		discisloss?ladder_option_disconnectisloss:ladder_option_none)<0)	    {		eventlog(eventlog_level_error,__FUNCTION__,"unable to update ladder stats");		xfree(ladder_info);		ladder_info = NULL;	    }	}	else	{	    int disc_set=0;	    	    for (i=0; i<realcount; i++)	    {		switch (game->results[i])		{		case game_result_win:		    account_inc_normal_wins(game->players[i],game->clienttag);		    account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_win));		    break;		case game_result_loss:		    account_inc_normal_losses(game->players[i],game->clienttag);		    account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_loss));		    break;		case game_result_draw:		    account_inc_normal_draws(game->players[i],game->clienttag);		    account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_draw));		    break;		case game_result_disconnect:		    if (discisloss)		    {			account_inc_normal_losses(game->players[i],game->clienttag);			account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_loss));		    }		    else		    {/* FIXME: Is the missing player always the first one in this array?  It seems like it should be   the person that created the game */			if (!disc_set)			{			    account_inc_normal_disconnects(game->players[i],game->clienttag);			    disc_set = 1;			}			account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_disconnect));		    }		    break;		default:		    eventlog(eventlog_level_error,__FUNCTION__,"bad normal game realplayer results[%u] = %u",i,game->results[i]);/* FIXME: Jung-woo fixed this here but we should find out what value results[i] has...   and why "discisloss" isn't set above in game_result_disconnect */#if 0		    /* commented out for loose disconnect policy */		    /* account_inc_normal_disconnects(game->players[i],game->clienttag); */#endif		    account_inc_normal_disconnects(game->players[i],game->clienttag);		    account_set_normal_last_result(game->players[i],game->clienttag,game_result_get_str(game_result_disconnect));		}		account_set_normal_last_time(game->players[i],game->clienttag,bnettime());	    }	}    }        if (game_get_type(game)!=game_type_ladder && prefs_get_report_all_games()!=1)    {	eventlog(eventlog_level_debug,__FUNCTION__,"not reporting normal games");	return 0;    }        {	struct tm * tmval;	char        dstr[64];		if (!(tmval = localtime(&now)))	    dstr[0] = '\0';	else	    sprintf(dstr,"%04d%02d%02d%02d%02d%02d",		    1900+tmval->tm_year,		    tmval->tm_mon+1,		    tmval->tm_mday,		    tmval->tm_hour,		    tmval->tm_min,		    tmval->tm_sec);	tempname = xmalloc(strlen(prefs_get_reportdir())+1+1+5+1+2+1+strlen(dstr)+1+6+1);	sprintf(tempname,"%s/_bnetd-gr_%s_%06u",prefs_get_reportdir(),dstr,game->id);	realname = xmalloc(strlen(prefs_get_reportdir())+1+2+1+strlen(dstr)+1+6+1);	sprintf(realname,"%s/gr_%s_%06u",prefs_get_reportdir(),dstr,game->id);    }        if (!(fp = fopen(tempname,"w")))    {	eventlog(eventlog_level_error,__FUNCTION__,"could not open report file \"%s\" for writing (fopen: %s)",tempname,pstrerror(errno));	if (ladder_info)	    xfree(ladder_info);	xfree(realname);	xfree(tempname);	return -1;    }        if (game->bad)	fprintf(fp,"[ game results ignored due to inconsistencies ]\n\n");    fprintf(fp,"name=\"%s\" id="GAMEID_FORMAT"\n",	    game_get_name(game),	    game->id);    fprintf(fp,"clienttag=%4s type=\"%s\" option=\"%s\"\n",	    tag_uint_to_str(clienttag_str,game->clienttag),	    game_type_get_str(game->type),	    game_option_get_str(game->option));    {	struct tm * gametime;	char        timetemp[GAME_TIME_MAXLEN];		if (!(gametime = localtime(&game->create_time)))	    strcpy(timetemp,"?");	else	    strftime(timetemp,sizeof(timetemp),GAME_TIME_FORMAT,gametime);	fprintf(fp,"created=\"%s\" ",timetemp);		if (!(gametime = localtime(&game->start_time)))	    strcpy(timetemp,"?");	else	    strftime(timetemp,sizeof(timetemp),GAME_TIME_FORMAT,gametime);	fprintf(fp,"started=\"%s\" ",timetemp);		if (!(gametime = localtime(&now)))	    strcpy(timetemp,"?");	else	    strftime(timetemp,sizeof(timetemp),GAME_TIME_FORMAT,gametime);	fprintf(fp,"ended=\"%s\"\n",timetemp);    }    {	char const * mapname;		if (!(mapname = game_get_mapname(game)))	    mapname = "?";		fprintf(fp,"mapfile=\"%s\" mapauth=\"%s\" mapsize=%ux%u tileset=\"%s\"\n",		mapname,		game_maptype_get_str(game_get_maptype(game)),		game_get_mapsize_x(game),game_get_mapsize_y(game),		game_tileset_get_str(game_get_tileset(game)));    }    fprintf(fp,"joins=%u maxplayers=%u\n",	    game_get_count(game),	    game_get_maxplayers(game));        if (!prefs_get_hide_addr())	fprintf(fp,"host=%s\n",addr_num_to_addr_str(game_get_addr(game),game_get_port(game)));        fprintf(fp,"\n\n");        if (game->clienttag==CLIENTTAG_DIABLORTL_UINT)	for (i=0; i<game->count; i++)	    fprintf(fp,"%-16s JOINED\n",account_get_name(game->players[i]));    else	if (ladder_info)	    for (i=0; i<realcount; i++)		fprintf(fp,"%-16s %-8s rating=%u [#%05u]  prob=%4.1f%%  K=%2u  adj=%+d\n",			account_get_name(game->players[i]),			game_result_get_str(game->results[i]),			ladder_info[i].oldrating,			ladder_info[i].oldrank,			ladder_info[i].prob*100.0,			ladder_info[i].k,			ladder_info[i].adj);	else	    for (i=0; i<realcount; i++)		fprintf(fp,"%-16s %-8s\n",			account_get_name(game->players[i]),			game_result_get_str(game->results[i]));    fprintf(fp,"\n\n");        if (ladder_info)	xfree(ladder_info);        for (i=0; i<realcount; i++)    {	if (game->report_heads[i])	    fprintf(fp,"%s\n",game->report_heads[i]);	else	    fprintf(fp,"[ game report header not available for player %u (\"%s\") ]\n",i+1,account_get_name(game->players[i]));	if (game->report_bodies[i])	    fprintf(fp,"%s\n",game->report_bodies[i]);	else	    fprintf(fp,"[ game report body not available for player %u (\"%s\") ]\n\n",i+1,account_get_name(game->players[i]));    }    fprintf(fp,"\n\n");        if (game->clienttag==CLIENTTAG_STARCRAFT_UINT ||	game->clienttag==CLIENTTAG_SHAREWARE_UINT ||        game->clienttag==CLIENTTAG_BROODWARS_UINT ||        game->clienttag==CLIENTTAG_WARCIIBNE_UINT)    {	for (i=0; i<realcount; i++)	    fprintf(fp,"%s's normal record is now %u/%u/%u (%u draws)\n",		    account_get_name(game->players[i]),		    account_get_normal_wins(game->players[i],game->clienttag),		    account_get_normal_losses(game->players[i],game->clienttag),		    account_get_normal_disconnects(game->players[i],game->clienttag),		    account_get_normal_draws(game->players[i],game->clienttag));    }    if (game->clienttag==CLIENTTAG_STARCRAFT_UINT ||        game->clienttag==CLIENTTAG_BROODWARS_UINT ||        game->clienttag==CLIENTTAG_WARCIIBNE_UINT)    {	fprintf(fp,"\n");	for (i=0; i<realcount; i++)	    fprintf(fp,"%s's standard ladder record is now %u/%u/%u (rating %u [#%05u]) (%u draws)\n",		    account_get_name(game->players[i]),		    account_get_ladder_wins(game->players[i],game->clienttag,ladder_id_normal),		    account_get_ladder_losses(game->players[i],game->clienttag,ladder_id_normal),		    account_get_ladder_disconnects(game->players[i],game->clienttag,ladder_id_normal),		    account_get_ladder_rating(game->players[i],game->clienttag,ladder_id_normal),		    account_get_ladder_rank(game->players[i],game->clienttag,ladder_id_normal),		    account_get_ladder_draws(game->players[i],game->clienttag,ladder_id_normal));    }    if (game->clienttag==CLIENTTAG_WARCIIBNE_UINT)    {	fprintf(fp,"\n");	for (i=0; i<realcount; i++)	    fprintf(fp,"%s's ironman ladder record is now %u/%u/%u (rating %u [#%05u]) (%u draws)\n",		    account_get_name(game->players[i]),		    account_get_ladder_wins(game->players[i],game->clienttag,ladder_id_ironman),		    account_get_ladder_losses(game->players[i],game->clienttag,ladder_id_ironman),		    account_get_ladder_disconnects(game->players[i],game->clienttag,ladder_id_ironman),		    account_get_ladder_rating(game->players[i],game->clienttag,ladder_id_ironman),		    account_get_ladder_rank(game->players[i],game->clienttag,ladder_id_ironman),		    account_get_ladder_draws(game->players[i],game->clienttag,ladder_id_ironman));    }        fprintf(fp,"\nThis game lasted %lu minutes (elapsed).\n",((unsigned long int)difftime(now,game->start_time))/60);        if (fclose(fp)<0)    {	eventlog(eventlog_level_error,__FUNCTION__,"could not close report file \"%s\" after writing (fclose: %s)",tempname,pstrerror(errno));	xfree(realname);	xfree(tempname);	return -1;    }        if (p_rename(tempname,realname)<0)    {	eventlog(eventlog_level_error,__FUNCTION__,"could not rename report file to \"%s\" (rename: %s)",realname,pstrerror(errno));	xfree(realname);	xfree(tempname);	return -1;    }        eventlog(eventlog_level_debug,__FUNCTION__,"game report saved as \"%s\"",realname);    xfree(realname);    xfree(tempname);    return 0;}extern unsigned int game_get_id(t_game const * game){    if (!game)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");        return 0;    }    return game->id;}extern char const * game_get_name(t_game const * game){    if (!game)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");        return NULL;    }    return game->name ? game->name : "BNet";}extern t_game_type game_get_type(t_game const * game){    if (!game)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");        return 0;    }    return game->type;}extern t_game_maptype game_get_maptype(t_game const * game){    if (!game)    {	eventlog(eventlog_level_error,__FUNCTION__,"got NULL game");        return game_maptype_none;    }    return game->maptype;}extern int game_set_maptype(t_game * game, t_game_maptype maptype){    if (!game)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -