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;iid,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;jreg_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;jreg[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;jreg_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;jreg[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)