NNGS围棋服务器修改用户的注册方式 作者: YKL NNGS围棋服务器默认的用户注册方式需要用户提供一个邮件帐号, 注册成功后会给用户提供的邮件帐号里发送一封确认邮件,用户的密码 就包含在这封邮件里。但在局域网里这么做显得有些繁琐,能不能不让 用户提供邮件帐号,把密码直接显示给用户呢? 打开$your directory/nngs-1.1.14/nrat目录中的comproc.c文件 ($your directory代表nngs-1.1.14目录所在的路径),找到com_register 函数,该函数就是Register命令对应的代码,代码如下: int com_register(int p, struct parameter * param) { char text[2048]; char *pname = param[0].val.word; char *email = param[1].val.word; const char *fullname = param[2].val.string; char passwd[sizeof parray[p].passwd]; char login[sizeof parray[p].login]; char tmp[200]; char salt[3]; int p1, p2; int i; int shuttime = globClock; int len; len=strlen(pname); if (len > MAX_NAME) { pcn_out(p, CODE_ERROR, FORMAT_PLAYER_NAME_IS_TOO_LONG); return COM_OK; } if (len < MIN_NAME) { pcn_out(p, CODE_ERROR, FORMAT_PLAYER_NAME_IS_TOO_SHORT); return COM_OK; } if (!strncasecmp(pname, "guest", 5)) { pcn_out(p, CODE_ERROR, FORMAT_IT_WOULD_NOT_BE_NICE_TO_REGISTER_GUEST); return COM_OK; } if (!alphastring(pname)) { pcn_out(p, CODE_ERROR, FORMAT_ILLEGAL_CHARACTERS_IN_PLAYER_NAME_ONLY_A_Z_A_Z_0_9_ALLOWED_); return COM_OK; } if (in_list_match("badname", pname)) { pcn_out(p, CODE_ERROR, FORMAT_THAT_NAME_IS_NOT_PERMITTED); return COM_OK; } if (param[2].type != TYPE_STRING) fullname = "Not Provided"; strcpy(login, pname); stolower(login); p1 = player_fetch(login); if (p1>=0 && parray[p1].slotstat.registered) { pcn_out(p, CODE_ERROR, FORMAT_A_PLAYER_BY_THE_NAME_s_IS_ALREADY_REGISTERED_, login); player_forget(p1); return COM_OK; } player_forget(p1); if (!chkaddr(email)) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_EMAIL_ADDRESSn); return COM_OK; } p1 = player_new(); do_copy(parray[p1].login, login, sizeof parray[0].login); do_copy(parray[p1].pname, pname, sizeof parray[0].pname); do_copy(parray[p1].rank, "NR", sizeof parray[0].rank); do_copy(parray[p1].ranked, "NR", sizeof parray[0].ranked); do_copy(parray[p1].srank, "NR", sizeof parray[0].srank); do_copy(parray[p1].fullname, fullname, sizeof parray[0].fullname); do_copy(parray[p1].email, email, sizeof parray[0].email); do_copy(parray[p1].RegDate, strltime((time_t *) &shuttime), sizeof parray[0].RegDate); for (i = 0; i < PASSLEN; i++) { passwd[i] = 'a' + rand() % 26; } passwd[i] = '\0'; salt[0] = 'a' + rand() % 26; salt[1] = 'a' + rand() % 26; salt[2] = '\0'; do_copy(parray[p1].passwd, mycrypt(passwd, salt), sizeof parray[0].passwd); parray[p1].adminLevel = ADMIN_REGISTERED_USER; parray[p1].slotstat.registered = 1; parray[p1].slotstat.valid = 1; player_dirty(p1); /* player_save(p1); this save can be omitted */ player_forget(p1); sprintf(text, "\nWelcome to %s! Here is your account info:\n\n\ Login Name: %s\n\ Full Name: %s\n\ Email Address: %s\n\ Initial Password: %s\n\n\ Host registered from: %s as %s \n\n\ If any of this information is incorrect, please contact the administrator\n\ to get it corrected at %s.\n\n\ Please write down your password, as it will be your initial password\n\ To access the server, telnet to %s\n\ Please change your password after logging in. See \"help password\"\n\ For additional help, type \"help welcome\" while on the server.\n\n\ On WWW, please try %s/\n\n\ Regards,\n\n\ NNGS admins\n\n--", server_name, pname, fullname, email, passwd, dotQuad(parray[p].thisHost), parray[p].pname, server_email, server_address,server_http); sprintf(tmp, "%s Account Created (%s)", server_name, pname); if ((i = mail_string_to_address(email, tmp, text)) < 0) Logit("mail_string_to_address(\"%s\", ...) returned %d", email, i); sprintf(text, "\n\ Login Name: %s\n\ Full Name: %s\n\ Email Address: %s\n\ Initial Password: %s\n\ Host registered from: %s \n\n--", pname, fullname, email, passwd, dotQuad(parray[p].thisHost)); /* Mail a copy to geek for testing / verification. */ if(geek_email) { if ((i = mail_string_to_address(geek_email, tmp, text)) < 0) Logit("mail_string_to_address(\"%s\", ...) returned %d", geek_email, i); } Logit("NewPlayer: %s [%s] %s (%s) by user %s", pname, email, fullname, passwd, parray[p].pname); pcn_out(p, CODE_INFO, FORMAT_YOU_ARE_NOW_REGISTERED_CONFIRMATION_TOGETHER_WITH_PASSWORD_IS_SENT_TO_YOURn); pcn_out_prompt(p, CODE_INFO, FORMAT_EMAIL_ADDRESS_sn, email); for (p2 = 0; p2 < parray_top; p2++) { /* Announce to all online admins */ if (!parray[p2].slotstat.online) continue; if (parray[p2].adminLevel < ADMIN_ADMIN) continue; pcn_out_prompt(p2, CODE_SHOUT, FORMAT_NEW_PLAYER_s_s_BY_ss_n, pname, email, (parray[p].slotstat.registered ? "" : "guest "), parray[p].pname); } new_players++; return COM_OK; } 我修改后的代码如下: int com_register(int p, struct parameter * param) { char text[2048]; char *pname = param[0].val.word; /* char *email = param[1].val.word; */ /*将接收email参数的语句注释掉,struct parameter 的定义见$your directory/nngs-1.1.14/nrat/command.h*/ const char *fullname = param[1].val.string; /*将fullname接收的参数由第三个参数改为第二个参数*/ char passwd[sizeof parray[p].passwd]; char login[sizeof parray[p].login]; char tmp[200]; char salt[3]; int p1, p2; int i; int shuttime = globClock; int len; len=strlen(pname); if (len > MAX_NAME) { pcn_out(p, CODE_ERROR, FORMAT_PLAYER_NAME_IS_TOO_LONG); return COM_OK; } if (len < MIN_NAME) { pcn_out(p, CODE_ERROR, FORMAT_PLAYER_NAME_IS_TOO_SHORT); return COM_OK; } if (!strncasecmp(pname, "guest", 5)) { pcn_out(p, CODE_ERROR, FORMAT_IT_WOULD_NOT_BE_NICE_TO_REGISTER_GUEST); return COM_OK; } if (!alphastring(pname)) { pcn_out(p, CODE_ERROR, FORMAT_ILLEGAL_CHARACTERS_IN_PLAYER_NAME_ONLY_A_Z_A_Z_0_9_ALLOWED_); return COM_OK; } if (in_list_match("badname", pname)) { pcn_out(p, CODE_ERROR, FORMAT_THAT_NAME_IS_NOT_PERMITTED); return COM_OK; } if (param[1].type != TYPE_STRING) fullname = "Not Provided"; /*前面将fullname接收的参数由第三个参数改为第二个参数,这里也相应更改*/ strcpy(login, pname); stolower(login); p1 = player_fetch(login); if (p1>=0 && parray[p1].slotstat.registered) { pcn_out(p, CODE_ERROR, FORMAT_A_PLAYER_BY_THE_NAME_s_IS_ALREADY_REGISTERED_, login); player_forget(p1); return COM_OK; } player_forget(p1); if (!chkaddr(email)) { pcn_out(p, CODE_ERROR, FORMAT_INVALID_EMAIL_ADDRESSn); return COM_OK; } p1 = player_new(); do_copy(parray[p1].login, login, sizeof parray[0].login); do_copy(parray[p1].pname, pname, sizeof parray[0].pname); do_copy(parray[p1].rank, "NR", sizeof parray[0].rank); do_copy(parray[p1].ranked, "NR", sizeof parray[0].ranked); do_copy(parray[p1].srank, "NR", sizeof parray[0].srank); do_copy(parray[p1].fullname, fullname, sizeof parray[0].fullname); do_copy(parray[p1].email, "Not Provided", sizeof parray[0].email); /*将email的值设为 "Not Provided"*/ do_copy(parray[p1].RegDate, strltime((time_t *) &shuttime), sizeof parray[0].RegDate); for (i = 0; i < PASSLEN; i++) { passwd[i] = 'a' + rand() % 26; } passwd[i] = '\0'; salt[0] = 'a' + rand() % 26; salt[1] = 'a' + rand() % 26; salt[2] = '\0'; do_copy(parray[p1].passwd, mycrypt(passwd, salt), sizeof parray[0].passwd); parray[p1].adminLevel = ADMIN_REGISTERED_USER; parray[p1].slotstat.registered = 1; parray[p1].slotstat.valid = 1; player_dirty(p1); /* player_save(p1); this save can be omitted */ player_forget(p1); /* sprintf(text, "\nWelcome to %s! Here is your account info:\n\n\ Login Name: %s\n\ Full Name: %s\n\ Email Address: %s\n\ Initial Password: %s\n\n\ Host registered from: %s as %s \n\n\ If any of this information is incorrect, please contact the administrator\n\ to get it corrected at %s.\n\n\ Please write down your password, as it will be your initial password\n\ To access the server, telnet to %s\n\ Please change your password after logging in. See \"help password\"\n\ For additional help, type \"help welcome\" while on the server.\n\n\ On WWW, please try %s/\n\n\ Regards,\n\n\ NNGS admins\n\n--", server_name, pname, fullname, email, passwd, dotQuad(parray[p].thisHost), parray[p].pname, server_email, server_address,server_http); sprintf(tmp, "%s Account Created (%s)", server_name, pname); */ /*这两句的内容就是服务器发给用户的确认邮件的内容,这里把它们注释掉。如果你仍采用邮件确认的 方式,你可以把它们的内容改成你喜欢的内容。*/ /* if ((i = mail_string_to_address(email, tmp, text)) < 0) Logit("mail_string_to_address(\"%s\", ...) returned %d", email, i); sprintf(text, "\n\ Login Name: %s\n\ Full Name: %s\n\ Email Address: %s\n\ Initial Password: %s\n\ Host registered from: %s \n\n--", pname, fullname, email, passwd, dotQuad(parray[p].thisHost)); */ /*与email有关的语句注释掉*/ /* Mail a copy to geek for testing / verification. */ /* if(geek_email) { if ((i = mail_string_to_address(geek_email, tmp, text)) < 0) Logit("mail_string_to_address(\"%s\", ...) returned %d", geek_email, i); } */ /*与email有关的语句注释掉*/ Logit("NewPlayer: %s [%s] %s (%s) by user %s", pname, "Not Provided", fullname, passwd, parray[p].pname); /*将email改 为"Not Provided"*/ pcn_out(p, CODE_INFO, FORMAT_YOU_ARE_NOW_REGISTERED_CONFIRMATION_TOGETHER_WITH_PASSWORD_IS_SENT_TO_YOURn); /* pcn_out_prompt(p, CODE_INFO, FORMAT_EMAIL_ADDRESS_sn, email); */ /*与email有关的语句 注释掉*/ pcn_out_prompt(p, CODE_INFO, FORMAT_PNAME_sn, pname); /*新增的输出用户名的语句*/ pcn_out_prompt(p, CODE_INFO, FORMAT_PASSWD_sn, passwd); /*新增的输出password的语句*/ for (p2 = 0; p2 < parray_top; p2++) { /* Announce to all online admins */ if (!parray[p2].slotstat.online) continue; if (parray[p2].adminLevel < ADMIN_ADMIN) continue; pcn_out_prompt(p2, CODE_SHOUT, FORMAT_NEW_PLAYER_s_s_BY_ss_n, pname, "Not Provided", (parray[p].slotstat.registered ? "" : "guest "), parray[p].pname); } /*将email改为"Not Provided"*/ new_players++; return COM_OK; } pcn_out和pcn_out_prompt语句用到的FORMAT_***参数的定义在$your directory/nngs-1.1.14/src/formats.h文件里。在这里我将formats.h文件里的 FORMAT_YOU_ARE_NOW_REGISTERED_CONFIRMATION_TOGETHER_WITH_PASSWORD_IS_SENT_TO_YOURn由"You are now registered! Confirmation together with password is sent to your\n"改为了"You are now registered!\n",并且在文件中 #define FORMAT_SERVER_VERSION_sn 843 ENG(FORMAT_SERVER_VERSION_sn,"Server version: %s\n"); 这一条定义后增加了两个定义: #define FORMAT_PNAME_sn 844 ENG(FORMAT_PNAME_sn,"your login name: %s\n"); #define FORMAT_PASSWD_sn 845 ENG(FORMAT_PASSWD_sn,"your password: %s\n"); 你也可以把定义的内容写成中文的。关于formats.h文件里定义的格式, 打开formats.h文件一看便知。 修改后重新make install一下即可。 现在用户注册时只需输入register login_ name full_name格式的命令 就可以了,密码会直接显示给用户。 别忘了修改一下register命令的帮助文件:)。 BTW:comproc.c文件包含了nngs里各个命令所对应的代码,你可以按你的 意愿尽情定制哦。 欢迎与我联系cccp401@sohu.com。