📄 inter.c
字号:
#include "mmo.h"
#include "char.h"
#include "socket.h"
#include "timer.h"
#include "db.h"
#include <string.h>
#include <stdlib.h>
#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<wis_delnum;i++){
struct WisData *wd=numdb_search(wis_db,wis_dellist[i]);
printf("inter: wis data id=%d time out : from %s to %s\n",
wd->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->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<ACCOUNT_REG_NUM;j++,p+=n){
if( sscanf(p,"%[^,],%d %n",buf,&v,&n)!=2 )
break;
memcpy(reg->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->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<ACCOUNT_REG_NUM && p<RFIFOW(fd,2);j++,p+=36){
memcpy(reg->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)<length) // 僷働僢僩偑枹拝
return 0;
return length;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -