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。