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