NNGS围棋服务器Rank命令的问题 作者: YKL 我在安装完NNGS围棋服务器后(见《如何在局域网中安装NNGS围棋服务器》一文), 运行时发现了一个问题如下: 新用户的段位默认为NR(这一点很正常),但是却无法用Rank命令设置段位。 无论设成几d或几k,总是显示信息“Rank set to NR”,而用户的段位仍是NR。 必须先把新用户的段位设为“???”,才能设置用户的段位。 打开$your directory/nngs-1.1.14/nrat目录中的comproc.c文件 ($your directory代表nngs-1.1.14目录所在的路径),找到com_ranked函数, 该函数就是Rank命令对应的代码,代码如下: int com_ranked(int p, struct parameter * param) { int len, level, rat; char temp[10], trnk; len = strlen(param[0].val.string); if((len > 3) || (len < 2)) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_RANK_VALID_RANKS_ARE_30K_1K_1D_6D_); return COM_OK; } do_copy(temp, param[0].val.string, sizeof temp); stolower(temp); switch(temp[1]) { case '?' : do_copy(parray[p].ranked, "???", sizeof parray[0].ranked); do_copy(parray[p].srank, "???", sizeof parray[0].srank); parray[p].rating = 1; parray[p].orating = 1; return COM_OK; case 'r' : do_copy(parray[p].ranked, "NR", sizeof parray[0].ranked); do_copy(parray[p].srank, "NR", sizeof parray[0].srank); parray[p].rating = 0; parray[p].orating = 0; parray[p].rated = 0; return COM_OK; default: break; } len=sscanf(temp, "%d%c", &level, &trnk); if(len==2) { switch(trnk) { case 'p': if(level < 1 || level > 20) len = -1; /* :-) */ break; case 'd': if(level < 1 || level > 6) len = -1; break; case 'k': if(level > 30 || level < 1) len = -1; break; default: len = -1; } } if(len!=2) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_RANK_VALID_RANKS_ARE_30K_1K_1D_6D_); return COM_OK; } if(!strcmp(parray[p].ranked, "NR")) { parray[p].orating = 0; } else { rat=parse_rank(level, trnk); sprintf(parray[p].ranked, "%d%c", level, trnk); parray[p].orating = (rat * 100) - 100; } pcn_out(p,CODE_INFO, FORMAT_RANK_SET_TO_sn, parray[p].ranked); pcn_out(p, CODE_INFO, FORMAT_PLEASE_EXPLAIN_YOUR_RANK_BY_USING_qSET_RANKq_ ); return COM_OK; } 我修改后的代码如下: int com_ranked(int p, struct parameter * param) { int len, level, rat; char temp[10], trnk; len = strlen(param[0].val.string); if((len > 3) || (len < 2)) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_RANK_VALID_RANKS_ARE_30K_1K_1D_6D_); return COM_OK; } do_copy(temp, param[0].val.string, sizeof temp); stolower(temp); /* switch(temp[1]) { case '?' : do_copy(parray[p].ranked, "???", sizeof parray[0].ranked); do_copy(parray[p].srank, "???", sizeof parray[0].srank); parray[p].rating = 1; parray[p].orating = 1; return COM_OK; case 'r' : do_copy(parray[p].ranked, "NR", sizeof parray[0].ranked); do_copy(parray[p].srank, "NR", sizeof parray[0].srank); parray[p].rating = 0; parray[p].orating = 0; parray[p].rated = 0; return COM_OK; default: break; } */ /*注:此处将原来的switch语句注释掉了*/ len=sscanf(temp, "%d%c", &level, &trnk); if(len==2) { switch(trnk) { case 'p': if(level < 1 || level > 20) len = -1; /* :-) */ break; case 'd': if(level < 1 || level > 6) len = -1; break; case 'k': if(level > 30 || level < 1) len = -1; break; default: len = -1; } } if(len!=2) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_RANK_VALID_RANKS_ARE_30K_1K_1D_6D_); return COM_OK; } switch(temp[1]) { case '?' : do_copy(parray[p].ranked, "???", sizeof parray[0].ranked); do_copy(parray[p].srank, "???", sizeof parray[0].srank); parray[p].rating = 1; parray[p].orating = 1; return COM_OK; case 'r' : do_copy(parray[p].ranked, "NR", sizeof parray[0].ranked); do_copy(parray[p].srank, "NR", sizeof parray[0].srank); parray[p].rating = 0; parray[p].orating = 0; parray[p].rated = 0; return COM_OK; default: do_copy(parray[p].ranked, param[0].val.string, sizeof parray[0].ranked); do_copy(parray[p].srank, param[0].val.string, sizeof parray[0].srank); } /*注:此处是新加的switch语句,与原来的相比区别在于default:后新加了两条语句*/ if(!strcmp(parray[p].ranked, "NR")) { parray[p].orating = 0; } else { rat=parse_rank(level, trnk); sprintf(parray[p].ranked, "%d%c", level, trnk); parray[p].orating = (rat * 100) - 100; } pcn_out(p,CODE_INFO, FORMAT_RANK_SET_TO_sn, parray[p].ranked); pcn_out(p, CODE_INFO, FORMAT_PLEASE_EXPLAIN_YOUR_RANK_BY_USING_qSET_RANKq_ ); return COM_OK; } 修改后重新 make install一下,问题解决。不过有一个小的后遗症: 不能用Rank命令把段位设为NR了。当然还有别的改法,你完全可以按你自己的想法改。 这个问题好像是程序本身的问题,也许原作者就是这个意图?不太明白。 BTW:comproc.c文件包含了nngs里各个命令所对应的代码,你可以按你的意愿尽情定制哦。 欢迎与我联系cccp401@sohu.com。