📄 login.c
字号:
break;
case 0x2714:
//printf("set users %s : %d\n",server[id].name,RFIFOL(fd,2));
server[id].users=RFIFOL(fd,2);
RFIFOSKIP(fd,6);
break;
case 0x2720: // GM
{
int newacc=0,oldacc,i=0,j;
if(RFIFOREST(fd)<4)
return 0;
if(RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
oldacc=RFIFOL(fd,4);
printf("gm search %d\n",oldacc);
if(strcmp(RFIFOP(fd,8),gm_pass)==0 &&
(oldacc<gm_start || oldacc>gm_last)){
for(j=gm_start,i=0;j<gm_last && i<auth_num;j++){
for(i=0;i<auth_num;i++){
if(auth_dat[i].account_id==j)
break;
}
}
if(i==auth_num){
newacc=j-1;
for(i=0;i<auth_num;i++){
if(auth_dat[i].account_id==oldacc){
auth_dat[i].account_id=newacc;
}
}
printf("change GM! %d=>%d\n",oldacc,newacc);
}else
printf("change GM error %d %s\n",oldacc,RFIFOP(fd,8));
}else
printf("change GM error %d %s\n",oldacc,RFIFOP(fd,8));
RFIFOSKIP(fd,RFIFOW(fd,2));
WFIFOW(fd,0)=0x2721;
WFIFOL(fd,2)=oldacc;
WFIFOL(fd,6)=newacc;
WFIFOSET(fd,10);
}
return 0;
case 0x2722: // changesex
{
int acc,sex,i=0,j=0;
if(RFIFOREST(fd)<4)
return 0;
if(RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
acc=RFIFOL(fd,4);
sex=RFIFOB(fd,8);
for(i=0;i<auth_num;i++){
// printf("%d,",auth_dat[i].account_id);
if(auth_dat[i].account_id==acc){
auth_dat[i].sex=sex;
j=1;
}
}
RFIFOSKIP(fd,RFIFOW(fd,2));
WFIFOW(fd,0)=0x2723;
WFIFOL(fd,2)=acc;
WFIFOB(fd,6)=sex;
WFIFOSET(fd,7);
}
return 0;
case 0x2728: { // save account_reg
int acc,p,i,j;
if(RFIFOREST(fd)<4)
return 0;
if(RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
acc=RFIFOL(fd,4);
for(i=0;i<auth_num;i++){
if(auth_dat[i].account_id==acc)
break;
}
if(i<auth_num){
unsigned char buf[4096];
for(p=8,j=0;p<RFIFOW(fd,2) && j<ACCOUNT_REG2_NUM;p+=36,j++){
memcpy(auth_dat[i].account_reg2[j].str,RFIFOP(fd,p),32);
auth_dat[i].account_reg2[j].value=RFIFOL(fd,p+32);
}
auth_dat[i].account_reg2_num=j;
// 懠偺僒乕僶乕傊億僗僩乮摨岰儘僌僀儞偑側偗傟偽憲傜側偔偰偄偄乯
memcpy(WBUFP(buf,0),RFIFOP(fd,0),RFIFOW(fd,2));
WBUFW(buf,0)=0x2729;
charif_sendallwos(fd,buf,WBUFW(buf,2));
// 曐懚
mmo_auth_sync();
}
RFIFOSKIP(fd,RFIFOW(fd,2));
// printf("login: save account_reg (from char)\n");
}break;
default:
printf("login: unknown packet %x! (from char).\n",RFIFOW(fd,0));
close(fd);
session[fd]->eof=1;
return 0;
}
}
return 0;
}
int parse_admin(int fd)
{
int i;
if(session[fd]->eof){
for(i=0;i<MAX_SERVERS;i++)
if(server_fd[i]==fd)
server_fd[i]=-1;
close(fd);
delete_session(fd);
return 0;
}
while(RFIFOREST(fd)>=2){
switch(RFIFOW(fd,0)){
case 0x7920: { // 傾僇僂儞僩儕僗僩
int st,ed,len;
if(RFIFOREST(fd)<11)
return 0;
st=RFIFOL(fd,2);
ed=RFIFOL(fd,6);
RFIFOSKIP(fd,11);
WFIFOW(fd,0)=0x7921;
if(st<0)st=0;
if(ed>END_ACCOUNT_NUM || ed<st || ed<=0)ed=END_ACCOUNT_NUM;
for(i=0,len=4;i<auth_num && len<30000;i++){
int account_id=auth_dat[i].account_id;
if( account_id>=st && account_id<=ed ){
WFIFOL(fd,len )=auth_dat[i].account_id;
memcpy(WFIFOP(fd,len+4),auth_dat[i].userid,24);
WFIFOB(fd,len+28)=auth_dat[i].sex;
WFIFOL(fd,len+53)=auth_dat[i].logincount;
WFIFOL(fd,len+57)=auth_dat[i].state;
len+=61;
}
}
WFIFOW(fd,2)=len;
WFIFOSET(fd,len);
}break;
case 0x7930: { // 傾僇僂儞僩嶌惉
struct mmo_account ma;
if(RFIFOREST(fd)<4 || RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
ma.userid=RFIFOP(fd, 4);
ma.passwd=RFIFOP(fd,28);
memcpy(ma.lastlogin,"-",2);
ma.sex=RFIFOB(fd,52);
WFIFOW(fd,0)=0x7931;
WFIFOW(fd,2)=0;
memcpy(WFIFOP(fd,4),RFIFOP(fd,4),24);
for(i=0;i<auth_num;i++){
if( strncmp(auth_dat[i].userid,ma.userid,24)==0 ){
WFIFOW(fd,2)=1;
break;
}
}
if(i==auth_num){
if( !mmo_auth_new(&ma,"( ladmin )",ma.sex) )
WFIFOW(fd,2)=1;
}
WFIFOSET(fd,28);
RFIFOSKIP(fd,RFIFOW(fd,2));
}break;
case 0x7932: // 傾僇僂儞僩嶍彍
WFIFOW(fd,0)=0x7933;
WFIFOW(fd,2)=1;
memcpy(WFIFOP(fd,4),RFIFOP(fd,4),24);
for(i=0;i<auth_num;i++){
if( strncmp(auth_dat[i].userid,RFIFOP(fd,4),24)==0 ){
auth_dat[i].userid[0]=0;
auth_dat[i].account_id=-1;
WFIFOW(fd,2)=0;
break;
}
}
WFIFOSET(fd,28);
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
case 0x7934: // 僷僗儚乕僪曄峏
WFIFOW(fd,0)=0x7935;
WFIFOW(fd,2)=1;
memcpy(WFIFOP(fd,4),RFIFOP(fd,4),24);
for(i=0;i<auth_num;i++){
if( strncmp(auth_dat[i].userid,RFIFOP(fd,4),24)==0 ){
memcpy(auth_dat[i].pass,RFIFOP(fd,28),24);
WFIFOW(fd,2)=0;
break;
}
}
WFIFOSET(fd,28);
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
case 0x7936: // 僶儞忬懺曄峏
WFIFOW(fd,0)=0x7937;
WFIFOW(fd,2)=1;
memcpy(WFIFOP(fd,4),RFIFOP(fd,4),24);
for(i=0;i<auth_num;i++){
if( strncmp(auth_dat[i].userid,RFIFOP(fd,4),24)==0 ){
auth_dat[i].state=RFIFOL(fd,28);
WFIFOW(fd,2)=0;
break;
}
}
WFIFOL(fd,28)=auth_dat[i].state;
WFIFOSET(fd,32);
RFIFOSKIP(fd,RFIFOW(fd,2));
break;
default:
close(fd);
session[fd]->eof=1;
return 0;
}
//WFIFOW(fd,0)=0x791f;
//WFIFOSET(fd,2);
}
return 0;
}
int parse_login(int fd)
{
struct mmo_account account;
int result,i;
if(session[fd]->eof){
for(i=0;i<MAX_SERVERS;i++)
if(server_fd[i]==fd)
server_fd[i]=-1;
close(fd);
delete_session(fd);
return 0;
}
if(RFIFOW(fd,0)<30000) {
if(RFIFOW(fd,0) == 0x64 || RFIFOW(fd,0) == 0x01dd)
printf("parse_login : %d %d %d %s\n",fd,RFIFOREST(fd),RFIFOW(fd,0),RFIFOP(fd,6));
else
printf("parse_login : %d %d %d\n",fd,RFIFOREST(fd),RFIFOW(fd,0));
}
while(RFIFOREST(fd)>=2){
switch(RFIFOW(fd,0)){
case 0x64: // 僋儔僀傾儞僩儘僌僀儞梫媮
case 0x01dd: // 埫崋壔儘僌僀儞梫媮
if(RFIFOREST(fd)< ((RFIFOW(fd,0)==0x64)?55:47))
return 0;
{
unsigned char *p=(unsigned char *)&session[fd]->client_addr.sin_addr;
login_log("client connection request %s from %d.%d.%d.%d" RETCODE,
RFIFOP(fd,6),p[0],p[1],p[2],p[3]);
}
if( !check_ip(session[fd]->client_addr.sin_addr.s_addr) ){
struct timeval tv;
char tmpstr[256];
gettimeofday(&tv,NULL);
strftime(tmpstr,24,"%Y-%m-%d %H:%M:%S",localtime(&(tv.tv_sec)));
sprintf(tmpstr+19,".%03d",(int)tv.tv_usec/1000);
login_log("access denied %s" RETCODE, tmpstr);
WFIFOW(fd,0)=0x6a;
WFIFOB(fd,2)=0x03;
WFIFOSET(fd,3);
}
account.userid = RFIFOP(fd,6);
account.passwd = RFIFOP(fd,30);
#ifdef PASSWORDENC
account.passwdenc= (RFIFOW(fd,0)==0x64)?0:PASSWORDENC;
#else
account.passwdenc=0;
#endif
result=mmo_auth(&account,fd);
if(result==100){
server_num=0;
for(i=0;i<MAX_SERVERS;i++){
if(server_fd[i]>=0){
WFIFOL(fd,47+server_num*32) = server[i].ip;
WFIFOW(fd,47+server_num*32+4) = server[i].port;
memcpy(WFIFOP(fd,47+server_num*32+6), server[i].name, 20);
WFIFOW(fd,47+server_num*32+26) = server[i].users;
WFIFOW(fd,47+server_num*32+28) = server[i].maintenance;
WFIFOW(fd,47+server_num*32+30) = server[i].new;
server_num++;
}
}
WFIFOW(fd,0)=0x69;
WFIFOW(fd,2)=47+32*server_num;
WFIFOL(fd,4)=account.login_id1;
WFIFOL(fd,8)=account.account_id;
WFIFOL(fd,12)=account.login_id2;
WFIFOL(fd,16)=0;
memcpy(WFIFOP(fd,20),account.lastlogin,24);
WFIFOB(fd,46)=account.sex;
WFIFOSET(fd,47+32*server_num);
if(auth_fifo_pos>=AUTH_FIFO_SIZE){
auth_fifo_pos=0;
}
auth_fifo[auth_fifo_pos].account_id=account.account_id;
auth_fifo[auth_fifo_pos].login_id1=account.login_id1;
auth_fifo[auth_fifo_pos].login_id2=account.login_id2;
auth_fifo[auth_fifo_pos].sex=account.sex;
auth_fifo[auth_fifo_pos].delflag=0;
auth_fifo_pos++;
} else {
memset(WFIFOP(fd,0),0,23);
WFIFOW(fd,0)=0x6a;
WFIFOB(fd,2)=result;
WFIFOSET(fd,23);
}
RFIFOSKIP(fd,(RFIFOW(fd,0)==0x64)?55:47);
break;
case 0x01db: // 埫崋壔Key憲怣梫媮
case 0x791a: // 娗棟僷働僢僩偱埫崋壔key梫媮
{
struct login_session_data *ld;
if(session[fd]->session_data){
printf("login: illeagal md5key request.");
close(fd);
session[fd]->eof=1;
return 0;
}
ld=session[fd]->session_data=calloc(sizeof(*ld), 1);
if(!ld){
printf("login: md5key request: out of memory !\n");
close(fd);
session[fd]->eof=1;
return 0;
}
// 埫崋壔僉乕惗惉
memset(ld->md5key,0,sizeof(ld->md5key));
ld->md5keylen=rand()%4+12;
for(i=0;i<ld->md5keylen;i++)
ld->md5key[i]=rand()%255+1;
RFIFOSKIP(fd,2);
WFIFOW(fd,0)=0x01dc;
WFIFOW(fd,2)=4+ld->md5keylen;
memcpy(WFIFOP(fd,4),ld->md5key,ld->md5keylen);
WFIFOSET(fd,WFIFOW(fd,2));
}
break;
case 0x2710: // Char僒乕僶乕愙懕梫媮
if(RFIFOREST(fd)<76)
return 0;
{
FILE *logfp=fopen(login_log_filename,"a");
if(logfp){
unsigned char *p=(unsigned char *)&session[fd]->client_addr.sin_addr;
fprintf(logfp,"server connection request %s @ %d.%d.%d.%d:%d (%d.%d.%d.%d)" RETCODE,
RFIFOP(fd,60),RFIFOB(fd,54),RFIFOB(fd,55),RFIFOB(fd,56),RFIFOB(fd,57),RFIFOW(fd,58),
p[0],p[1],p[2],p[3]);
fclose(logfp);
}
}
account.userid = RFIFOP(fd,2);
account.passwd = RFIFOP(fd,26);
account.passwdenc = 0;
result = mmo_auth(&account,fd);
if(result == 100 && account.sex==2 && account.account_id<MAX_SERVERS && server_fd[account.account_id]<0){
server[account.account_id].ip=RFIFOL(fd,54);
server[account.account_id].port=RFIFOW(fd,58);
memcpy(server[account.account_id].name,RFIFOP(fd,60),20);
server[account.account_id].users=0;
server[account.account_id].maintenance=RFIFOW(fd,82);
server[account.account_id].new=RFIFOW(fd,84);
server_fd[account.account_id]=fd;
WFIFOW(fd,0)=0x2711;
WFIFOB(fd,2)=0;
WFIFOSET(fd,3);
session[fd]->func_parse=parse_fromchar;
realloc_fifo(fd,FIFOSIZE_SERVERLINK,FIFOSIZE_SERVERLINK);
} else {
WFIFOW(fd,0)=0x2711;
WFIFOB(fd,2)=3;
WFIFOSET(fd,3);
}
RFIFOSKIP(fd,86);
return 0;
case 0x7530: // Athena忣曬強摼
WFIFOW(fd,0)=0x7531;
WFIFOB(fd,2)=ATHENA_MAJOR_VERSION;
WFIFOB(fd,3)=ATHENA_MINOR_VERSION;
WFIFOB(fd,4)=ATHENA_REVISION;
WFIFOB(fd,5)=ATHENA_RELEASE_FLAG;
WFIFOB(fd,6)=ATHENA_OFFICIAL_FLAG;
WFIFOB(fd,7)=ATHENA_SERVER_LOGIN;
WFIFOW(fd,8)=ATHENA_MOD_VERSION;
WFIFOSET(fd,10);
RFIFOSKIP(fd,2);
break;
case 0x7532: // 愙懕偺愗抐(default偲張棟偼堦弿偩偑柧帵揑偵偡傞偨傔)
close(fd);
session[fd]->eof=1;
return 0;
case 0x7918: // 娗棟儌乕僪儘僌僀儞
{
struct login_session_data *ld=session[fd]->session_data;
if(RFIFOREST(fd)<4 || RFIFOREST(fd)<RFIFOW(fd,2))
return 0;
WFIFOW(fd,0)=0x7919;
WFIFOB(fd,2)=1;
if(RFIFOW(fd,4)==0){ // 僾儗乕儞
if(strcmp(RFIFOP(fd,6),admin_pass)==0){
WFIFOB(fd,2)=0;
session[fd]->func_parse=parse_admin;
}
}else{ // 埫崋壔
if(!ld){
printf("login: md5key not created for admin login\n");
}else{
char md5str[64]="",md5bin[32];
if(RFIFOW(fd,4)==1){
strcpy(md5str,ld->md5key);
strcat(md5str,admin_pass);
}else if(RFIFOW(fd,4)==2){
strcpy(md5str,admin_pass);
strcat(md5str,ld->md5key);
};
MD5_String2binary(md5str,md5bin);
if(memcmp(md5bin,RFIFOP(fd,6),16)==0){
WFIFOB(fd,2)=0;
session[fd]->func_parse=parse_admin;
}
}
}
WFIFOSET(fd,3);
RFIFOSKIP(fd,RFIFOW(fd,2));
}
break;
default:
close(fd);
session[fd]->eof=1;
return 0;
}
}
return 0;
}
int login_config_read(const char *cfgName)
{
int i;
char line[1024],w1[1024],w2[1024];
FILE *fp;
fp=fopen(cfgName,"r");
if(fp==NULL){
printf("file not found: %s\n",cfgName);
return 1;
}
while(fgets(line,1020,fp)){
if(line[0] == '/' && line[1] == '/')
continue;
i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2);
if(i!=2)
continue;
if(strcmpi(w1,"admin_pass")==0){
strcpy(admin_pass,w2);
}
else if(strcmpi(w1,"gm_pass")==0){
strcpy(gm_pass,w2);
}
else if(strcmpi(w1,"new_account")==0){
new_account_flag = atoi(w2);
}
else if(strcmpi(w1,"login_port")==0){
login_port=atoi(w2);
}
else if(strcmpi(w1,"account_filename")==0){
strcpy(account_filename,w2);
}
else if(strcmpi(w1,"gm_account_filename")==0){
strcpy(GM_account_filename,w2);
}
else if(strcmpi(w1,"order")==0){
access_order=atoi(w2);
if(strcmpi(w2,"deny,allow")==0) access_order=ACO_DENY_ALLOW;
if(strcmpi(w2,"allow,deny")==0) access_order=ACO_ALLOW_DENY;
if(strcmpi(w2,"mutual-failture")==0) access_order=ACO_MUTUAL_FAILTURE;
}
else if(strcmpi(w1,"allow")==0){
if( strcmpi(w2,"clear")==0 ){
if(access_allow)
free(access_allow);
access_allow=NULL;
access_allownum=0;
}else{
if(access_allow)
access_allow=realloc( access_allow, (access_allownum+1)*ACO_STRSIZE);
else
access_allow=calloc( ACO_STRSIZE , 1);
if(strcmpi(w2,"all")==0)
access_allow[(access_allownum++)*ACO_STRSIZE]=0;
else if(w2[0])
strcpy( access_allow+(access_allownum++)*ACO_STRSIZE,w2 );
}
}
else if(strcmpi(w1,"deny")==0){
if( strcmpi(w2,"clear")==0 ){
if(access_deny)
free(access_deny);
access_deny=NULL;
access_denynum=0;
}else{
if(access_deny)
access_deny=realloc( access_deny,(access_denynum+1)*ACO_STRSIZE);
else
access_deny=calloc( ACO_STRSIZE , 1);
if(strcmpi(w2,"all")==0)
access_deny[(access_denynum++)*ACO_STRSIZE]=0;
else if(w2[0])
strcpy( access_deny+(access_denynum++)*ACO_STRSIZE,w2 );
}
}
else if(strcmpi(w1,"login_log_filename")==0){
strcpy(login_log_filename,w2);
}
else if(strcmpi(w1,"import")==0){
login_config_read(w2);
}
}
fclose(fp);
return 0;
}
int do_init(int argc,char **argv)
{
int i;
login_config_read( (argc>1)?argv[1]:LOGIN_CONF_NAME );
srand(time(NULL));
for(i=0;i<AUTH_FIFO_SIZE;i++){
auth_fifo[i].delflag=1;
}
for(i=0;i<MAX_SERVERS;i++){
server_fd[i]=-1;
}
make_listen_port(login_port);
mmo_auth_init();
read_gm_account();
set_termfunc(mmo_auth_sync);
set_defaultparse(parse_login);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -