www.pudn.com > 传奇3源代码.rar > inter.c
#include "mmo.h" #include "char.h" #include "socket.h" #include "timer.h" #include "db.h" #include#include #include "inter.h" #include "int_party.h" #include "int_guild.h" #include "int_storage.h" #include "int_pet.h" #include "lock.h" #define WISDATA_TTL (60*1000) // Wis僨乕僞偺惗懚帪娫(60昩) #define WISDELLIST_MAX 128 // Wis僨乕僞嶍彍儕僗僩偺梫慺悢 char inter_log_filename[1024]="log/inter.log"; char accreg_txt[1024]="save/accreg.txt"; static struct dbt *accreg_db=NULL; struct accreg { int account_id,reg_num; struct global_reg reg[ACCOUNT_REG_NUM]; }; int party_share_level = 10; // 憲怣僷働僢僩挿儕僗僩 int inter_send_packet_length[]={ -1,-1,27, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, 35,-1,11,15, 34,29, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, 9, 9,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,-1, 7, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; // 庴怣僷働僢僩挿儕僗僩 int inter_recv_packet_length[]={ -1,-1, 7, 0, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, 72, 6,52,14, 10,29, 6,-1, 34, 0, 0, 0, 0, 0, 0, 0, -1, 6,-1, 0, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1, 5, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48,14,-1, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; struct WisData { int id,fd,count,len; unsigned long tick; unsigned char src[24],dst[24],msg[512]; }; static struct dbt * wis_db = NULL; static int wis_dellist[WISDELLIST_MAX], wis_delnum; // WIS僨乕僞偺惗懚僠僃僢僋 int check_ttl_wisdata_sub(void *key,void *data,va_list ap) { unsigned long tick; struct WisData *wd=(struct WisData *)data; tick=va_arg(ap,unsigned long); if( DIFF_TICK(tick,wd->tick)>WISDATA_TTL && wis_delnum< WISDELLIST_MAX ){ wis_dellist[wis_delnum++]=wd->id; } return 0; } int check_ttl_wisdata() { unsigned long tick=gettick(); int i; do{ wis_delnum=0; numdb_foreach( wis_db, check_ttl_wisdata_sub, tick ); for(i=0;i id,wd->src,wd->dst); numdb_erase(wis_db,wd->id); free(wd); } }while(wis_delnum>=WISDELLIST_MAX); return 0; } //-------------------------------------------------------- // 傾僇僂儞僩曄悢傪暥帤楍傊曄姺 int inter_accreg_tostr(char *str,struct accreg *reg) { int j; char *p=str; p+=sprintf(p,"%d\t",reg->account_id); for(j=0;j reg_num;j++){ p+=sprintf(p,"%s,%d ",reg->reg[j].str,reg->reg[j].value); } return 0; } // 傾僇僂儞僩曄悢傪暥帤楍偐傜曄姺 int inter_accreg_fromstr(const char *str,struct accreg *reg) { int j,v,n; char buf[128]; const char *p=str; if( sscanf(p,"%d\t%n",®->account_id,&n )!=1 || reg->account_id<=0) return 1; for(j=0,p+=n;j reg[j].str,buf,32); reg->reg[j].value=v; } reg->reg_num=j; return 0; } // 傾僇僂儞僩曄悢偺撉傒崬傒 int inter_accreg_init() { char line[8192]; FILE *fp; int c=0; struct accreg *reg; accreg_db=numdb_init(); if( (fp=fopen(accreg_txt,"r"))==NULL ) return 1; while(fgets(line,sizeof(line),fp)){ reg=calloc(sizeof(struct accreg), 1); if(reg==NULL){ printf("inter: accreg: out of memory!\n"); exit(0); } if(inter_accreg_fromstr(line,reg)==0 && reg->account_id>0){ numdb_insert(accreg_db,reg->account_id,reg); }else{ printf("inter: accreg: broken data [%s] line %d\n",accreg_txt,c); free(reg); } c++; } fclose(fp); // printf("inter: %s read done (%d)\n",accreg_txt,c); return 0; } // 傾僇僂儞僩曄悢偺僙乕僽梡 int inter_accreg_save_sub(void *key,void *data,va_list ap) { char line[8192]; FILE *fp; struct accreg *reg=(struct accreg *)data; if(reg->reg_num>0){ inter_accreg_tostr(line,reg); fp=va_arg(ap,FILE *); fprintf(fp,"%s" RETCODE,line); } return 0; } // 傾僇僂儞僩曄悢偺僙乕僽 int inter_accreg_save() { FILE *fp; int lock; if( (fp=lock_fopen(accreg_txt,&lock))==NULL ){ printf("int_accreg: cant write [%s] !!! data is lost !!!\n",accreg_txt); return 1; } numdb_foreach(accreg_db,inter_accreg_save_sub,fp); lock_fclose(fp,accreg_txt,&lock); // printf("inter: %s saved.\n",accreg_txt); return 0; } //-------------------------------------------------------- /*========================================== * 愝掕僼傽僀儖傪撉傒崬傓 *------------------------------------------ */ int inter_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)){ i=sscanf(line,"%[^:]: %[^\r\n]",w1,w2); if(i!=2) continue; if(strcmpi(w1,"storage_txt")==0){ strncpy(storage_txt,w2,sizeof(storage_txt)); } else if(strcmpi(w1,"party_txt")==0){ strncpy(party_txt,w2,sizeof(party_txt)); } else if(strcmpi(w1,"guild_txt")==0){ strncpy(guild_txt,w2,sizeof(guild_txt)); } else if(strcmpi(w1,"pet_txt")==0){ strncpy(pet_txt,w2,sizeof(pet_txt)); } else if(strcmpi(w1,"castle_txt")==0){ strncpy(castle_txt,w2,sizeof(castle_txt)); } else if(strcmpi(w1,"accreg_txt")==0){ strncpy(accreg_txt,w2,sizeof(accreg_txt)); } else if(strcmpi(w1,"guild_storage_txt")==0){ strncpy(guild_storage_txt,w2,sizeof(guild_storage_txt)); } else if(strcmpi(w1,"party_share_level")==0){ party_share_level=atoi(w2); if(party_share_level < 0) party_share_level = 0; } else if(strcmpi(w1,"inter_log_filename")==0){ strcpy(inter_log_filename,w2); } else if(strcmpi(w1,"import")==0){ inter_config_read(w2); } } fclose(fp); return 0; } // 儘僌彂偒弌偟 int inter_log(char *fmt,...) { FILE *logfp; va_list ap; va_start(ap,fmt); logfp=fopen(inter_log_filename,"a"); if(logfp){ vfprintf(logfp,fmt,ap); fclose(logfp); } va_end(ap); return 0; } // 僙乕僽 int inter_save() { inter_party_save(); inter_guild_save(); inter_storage_save(); inter_guild_storage_save(); inter_pet_save(); inter_accreg_save(); return 0; } // 弶婜壔 int inter_init(const char *file) { inter_config_read(file); wis_db = numdb_init(); inter_party_init(); inter_guild_init(); inter_storage_init(); inter_pet_init(); inter_accreg_init(); return 0; } // 儅僢僾僒乕僶乕愙懕 int inter_mapif_init(int fd) { inter_guild_mapif_init(fd); return 0; } //-------------------------------------------------------- // GM儊僢僙乕僕憲怣 int mapif_GMmessage(unsigned char *mes,int len) { unsigned char buf[len]; WBUFW(buf,0)=0x3800; WBUFW(buf,2)=len; memcpy(WBUFP(buf,4),mes,len-4); mapif_sendall(buf,len); // printf("inter server: GM:%d %s\n",len,mes); return 0; } // Wis憲怣 int mapif_wis_message(struct WisData *wd) { unsigned char buf[1024]; WBUFW(buf, 0)=0x3801; WBUFW(buf, 2)=8 + 48 +wd->len; WBUFL(buf, 4)=wd->id; memcpy(WBUFP(buf, 8),wd->src,24); memcpy(WBUFP(buf,32),wd->dst,24); memcpy(WBUFP(buf,56),wd->msg,wd->len); wd->count = mapif_sendall(buf,WBUFW(buf,2)); return 0; } // Wis憲怣寢壥 int mapif_wis_end(struct WisData *wd,int flag) { unsigned char buf[32]; WBUFW(buf, 0)=0x3802; memcpy(WBUFP(buf, 2),wd->src,24); WBUFB(buf,26)=flag; mapif_send(wd->fd,buf,27); // printf("inter server wis_end %d\n",flag); return 0; } // 傾僇僂儞僩曄悢憲怣 int mapif_account_reg(int fd,unsigned char *src) { unsigned char buf[4096]; memcpy(WBUFP(buf,0),src,WBUFW(src,2)); WBUFW(buf, 0)=0x3804; mapif_sendallwos(fd,buf,WBUFW(buf,2)); return 0; } // 傾僇僂儞僩曄悢梫媮曉怣 int mapif_account_reg_reply(int fd,int account_id) { struct accreg *reg=numdb_search(accreg_db,account_id); WFIFOW(fd,0)=0x3804; WFIFOL(fd,4)=account_id; if(reg==NULL){ WFIFOW(fd,2)=8; }else{ int j,p; for(j=0,p=8;j reg_num;j++,p+=36){ memcpy(WFIFOP(fd,p),reg->reg[j].str,32); WFIFOL(fd,p+32)=reg->reg[j].value; } WFIFOW(fd,2)=p; } WFIFOSET(fd,WFIFOW(fd,2)); return 0; } //-------------------------------------------------------- // GM儊僢僙乕僕憲怣 int mapif_parse_GMmessage(int fd) { mapif_GMmessage(RFIFOP(fd,4),RFIFOW(fd,2)); return 0; } // Wis憲怣梫媮 int mapif_parse_WisRequest(int fd) { struct WisData* wd; static int wisid=0; if( RFIFOW(fd,2)-52 >= sizeof(wd->msg) ){ printf("inter: Wis message size too long.\n"); return 0; } wd = (struct WisData *)calloc(sizeof(struct WisData), 1); if(wd==NULL){ // Wis憲怣幐攕乮僷働僢僩傪憲傞昁梫偁傝偐傕乯 printf("inter: WisRequest: out of memory !\n"); return 0; } check_ttl_wisdata(); wd->id = ++wisid; wd->fd = fd; wd->len= RFIFOW(fd,2)-52; memcpy(wd->src, RFIFOP(fd, 4), 24); memcpy(wd->dst, RFIFOP(fd,28), 24); memcpy(wd->msg, RFIFOP(fd,52), wd->len); wd->tick = gettick(); numdb_insert(wis_db, wd->id, wd); mapif_wis_message(wd); return 0; } // Wis憲怣寢壥 int mapif_parse_WisReply(int fd) { int id=RFIFOL(fd,2),flag=RFIFOB(fd,6); struct WisData *wd = numdb_search(wis_db, id); if(wd==NULL) return 0; // 僞僀儉傾僂僩偟偨偐ID偑懚嵼偟側偄 if( (--wd->count)==0 || flag!=1){ mapif_wis_end(wd,flag); numdb_erase(wis_db, id); free(wd); } return 0; } // 傾僇僂儞僩曄悢曐懚梫媮 int mapif_parse_AccReg(int fd) { int j,p; struct accreg *reg=numdb_search(accreg_db,RFIFOL(fd,4)); if(reg==NULL){ if((reg=calloc(sizeof(struct accreg), 1))==NULL){ printf("inter: accreg: out of memory !\n"); exit(0); } reg->account_id=RFIFOL(fd,4); numdb_insert(accreg_db,RFIFOL(fd,4),reg); } for(j=0,p=8;j reg[j].str,RFIFOP(fd,p),32); reg->reg[j].value=RFIFOL(fd,p+32); } reg->reg_num=j; inter_accreg_save(); // 曐懚 mapif_account_reg(fd,RFIFOP(fd,0)); // 懠偺MAP僒乕僶乕偵憲怣 return 0; } // 傾僇僂儞僩曄悢憲怣梫媮 int mapif_parse_AccRegRequest(int fd) { // printf("mapif: accreg request\n"); return mapif_account_reg_reply(fd,RFIFOL(fd,2)); } //-------------------------------------------------------- // map server 偐傜偺捠怣乮侾僷働僢僩偺傒夝愅偡傞偙偲乯 // 僄儔乕側傜0(false)丄張棟偱偒偨側傜1丄 // 僷働僢僩挿偑懌傝側偗傟偽2傪偐偊偝側偗傟偽側傜側偄 int inter_parse_frommap(int fd) { int cmd=RFIFOW(fd,0); int len=0; // inter嶪娗妽偐傪挷傋傞 if(cmd<0x3000 || cmd>=0x3000+( sizeof(inter_recv_packet_length)/ sizeof(inter_recv_packet_length[0]) ) ) return 0; // 僷働僢僩挿傪挷傋傞 if( (len=inter_check_length(fd,inter_recv_packet_length[cmd-0x3000]))==0 ) return 2; switch(cmd){ case 0x3000: mapif_parse_GMmessage(fd); break; case 0x3001: mapif_parse_WisRequest(fd); break; case 0x3002: mapif_parse_WisReply(fd); break; case 0x3004: mapif_parse_AccReg(fd); break; case 0x3005: mapif_parse_AccRegRequest(fd); break; default: if( inter_party_parse_frommap(fd) ) break; if( inter_guild_parse_frommap(fd) ) break; if( inter_storage_parse_frommap(fd) ) break; if( inter_pet_parse_frommap(fd) ) break; return 0; } RFIFOSKIP(fd, len ); return 1; } // RFIFO偺僷働僢僩挿妋擣 // 昁梫僷働僢僩挿偑偁傟偽僷働僢僩挿丄傑偩懌傝側偗傟偽0 int inter_check_length(int fd,int length) { if(length==-1){ // 壜曄僷働僢僩挿 if(RFIFOREST(fd)<4) // 僷働僢僩挿偑枹拝 return 0; length = RFIFOW(fd,2); } if(RFIFOREST(fd)