#define _MAIN_C_ #include "main.h" #include "util.h" #include "mail.h" #include "db.h" #include "saacproto_util.h" #include "saacproto_serv.h" // CoolFish: Family 2001/5/9 #include "acfamily.h" #include "version.h" #ifdef _SEND_EFFECT // WON ADD 送下雪、下雨等特效 #include "recv.h" #endif #include "md5.h" #include "char.h" #include "attestation.h" #ifdef _SASQL #include "sasql.h" #endif #include "longzoro.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "lock.h" #define BACKLOGNUM 5 int worksockfd; static int findregBlankMemBuf( void ); static int unregMemBuf( int index ); static int findregBlankCon( void ); static int getFreeMem( void ); static int appendReadBuffer( int index, char *data, int len ); static int appendWriteBuffer( int index , char *data, int len ); static int appendMemBufList( int top, char *data, int len ); static int consumeMemBufList( int top, char *out, int len, int flag, int copyflag ); static int getLineReadBuffer( int index, char *buf, int len ); void logerr(char *token); struct membuf { int use; char buf[512]; // char buf[1024*128]; int len; int next; }; struct connection { int use; int fd; int mbtop_ri; int mbtop_wi; struct sockaddr_in remoteaddr; int closed_by_remote; }; struct membuf *mb; int mbsize; int mbuse ; int cpuuse; int mainsockfd; /* accept 及 域娄醒卞中木月 */ struct sockaddr_in localaddr; /* bind 允月失玉伊旦 */ struct connection *con; /* 戊生弁扑亦件 */ static int mb_finder=0; /* mb及坞五毛腹绸允月凶户及 腹绸玄永皿及匏 筏盛迕 */ // WON FIX //char tmpbuf[65536]; char tmpbuf[1024*1024]; //char tmpbuf[65536*3]; /* read迕 */ struct timeval select_timeout; time_t sys_time =0; // Robin add extern gmsv gs[MAXCONNECTION]; int tcpstruct_init( char *addr, int port, int timeout_ms, int mem_use, int deb); int tcpstruct_accept1( void ); int tcpstruct_accept( int *tis , int ticount ); int tcpstruct_close( int ti ); int tcpstruct_read( int ti , char *buf , int len ); int tcpstruct_readline( int ti , char *buf , int len ,int k ,int r); int tcpstruct_readline_chop( int ti , char *buf, int len ); int tcpstruct_write( int ti , char *buf , int len ); int tcpstruct_countmbuse( void ); int tcpstruct_connect( char *addr , int port ); void set_nodelay( int sock ); #define OK 0 /* 岳 */ #define TCPSTRUCT_ENOMEM -1 /* malloc 撩 */ #define TCPSTRUCT_ESOCK -2 /* socket 撩 */ #define TCPSTRUCT_EBIND -3 /* bind 撩 */ #define TCPSTRUCT_ELISTEN -4 /* listen 撩 */ #define TCPSTRUCT_EBUG -6 /* 田弘匹丐月 */ #define TCPSTRUCT_EINVCIND -7 /* con尺及index互云井仄中方 */ #define TCPSTRUCT_EREADFIN -8 /* read 允月犯□正互卅仁化 closed by remote */ #define TCPSTRUCT_EHOST -9 /* gethostbyname 撩 */ #define TCPSTRUCT_ECONNECT -10 /* connect 撩 */ #define TCPSTRUCT_ECFULL -11 /* con 互中匀天中 */ #define TCPSTRUCT_ETOOLONG -12 /* 垫互卅互允亢 */ #define TCPSTRUCT_EMBFULL -13 /* mb 互中匀天中 */ #define TCPSTRUCT_ECLOSEAGAIN -14 /* close 互2荚今木凶 */ int port; /* 必□丞扔□田□互涛粮仄化仁月禾□玄 */ int Total_Charlist; int Expired_mail; int Del_Family_or_Member; int Write_Family; #ifdef _IP_VIP char myip[5][32]; #endif #ifdef _SAVE_ZIP int SAVEZIP = 0; void savezipfile( void); #endif // Nuke start char *chartime() { static char buf[80]; time_t t; t=time(0); strcpy(buf,ctime(&t)); buf[strlen(buf)-1]=0; return(buf); } #ifdef _ANGEL_SUMMON extern struct MissionTable missiontable[MAXMISSIONTABLE]; static int initMissionTable( void ); int saveMissionTable( void ); void checkMissionTimelimit( void); #endif /* sigaction白弁 */ void sighandle( int a ) { if (a==SIGUSR1) log("sigusr1信号!\n"); log("得到一个信号! 异常中断......\n" ); writeFamily(familydir); writeFMPoint(fmpointdir); writeFMSMemo(fmsmemodir); #ifdef _ANGEL_SUMMON saveMissionTable(); #endif exit(1); } // Arminius 7.20 memory unlock void sigusr1(int a) { int i; FILE *f; char key[4096],buf[4096]; signal(SIGUSR1, sigusr1); f = fopen("./unlock.arg", "r"); if (f) { memset(key, 0, 4096); fread(key, 4096, 1, f); for (i=0; i ./sigusr1.result", buf); system(key); break; #ifdef _SEND_EFFECT // WON ADD 送下雪、下雨等特效 case 'E': log("\nAC 向 GS 发送下雪特效!!\n"); SendEffect(&key[1]); break; #endif case 'L': // Robin 列出所有Server连线 log("\nList All Server Conncet!!!!!\n"); for( i =0; i 0){ log( "同IP允许同时登陆:%d次\n",sameipmun ); }else{ log( "同IP允许同时登陆:无限制\n" ); } } else if( strcmp( command , "CPUUSE" ) == 0 ){ cpuuse = atoi( param ); log( "CPU使用频率:%d秒\n",cpuuse ); } #ifdef _OLDPS_TO_MD5PS else if( strcmp( command , "USEMD5" ) == 0 ){ usemd5 = atoi( param ); log( "是否使用MD5密码:%d\n",usemd5 ); } #endif #ifdef _AUTO_BACKUP else if( strcmp( command , "AUTOBACKUPDAY" ) == 0 ){ autobackupday = atoi( param ); log( "每隔%d天备份一次数据!\n",autobackupday ); }else if( strcmp( command , "AUTOBACKUPHOUR" ) == 0 ){ autobackuphour = atoi( param ); log( "每次在%d点进行备份!\n",autobackuphour ); } #endif #ifdef _LOTTERY_SYSTEM else if( strcmp( command , "LOTTERYSYSTEM" ) == 0 ){ lotterysystem = atoi( param ); log( "每隔%d天开一次奖!\n",lotterysystem ); } #endif #ifdef _SAVE_ZIP else if( strcmp( command , "savezip" ) == 0 ){ SAVEZIP = atoi(param); log( "是否自动备份:%s\n",SAVEZIP>0?"是":"否"); } #endif else if( strcmp( command , "servid" ) == 0 ){ servid = atoi( param ); log( "服务器ID!\n", servid ); } } fclose(fp); return 0; } static void parseOpts( int argc, char **argv ) { int c , option_index; while(1){ static struct option long_options[] = { {"nice" , 1 , 0 , 'n'}, {"buy" , 0 , 0 , 'b'}, {"cost" , 0 , 0 , 'c'}, {"help" , 0 , 0 , 'h' }, {"userinfo",0 , 0 , 'i'}, {"lockuser",0 , 0 , 'l'}, {"transmd5",0 , 0 , 'm'}, {"del" , 0 , 0 , 'd'}, {"trans" , 0 , 0 , 't'} }; c = getopt_long( argc , argv , "n:bchilmdt" , long_options , &option_index ); if( c == -1 )break; switch( c ){ case 'h': fprintf( stderr , "使用方法: saac [-h] [-w port] [-w port] ... \n" "-h : 显示saac的帮助\n" "-w port : 添加一个工作站进程端口\n" "Copyright 2006 龙zoro工作室 " "( Longzoro System Supply )\n"); exit(0); break; case 'i': { int i; char buf[256]="9088"; int len=strlen(buf); char crypto_key[]={"aBcDeFgHiJkLmNoPqRsTuVwXyZ"}; for(i=0;i= 2){ int gold; printf("请输入您要制作石币的面值:"); scanf("%d", &gold); sprintf(coststr, "%d", gold); } printf("请输入您要制作的充值卡数量:"); scanf("%d", &num); sasql_init(); sasql_OnlineBuy_add(coststr, type, num); sasql_close(); } #endif exit(0); break; case 'c': #ifdef _ONLINE_COST { int cost = 0,num = 0,point = 0; printf("请输入您要制作的充值卡面值:"); scanf("%d", &cost); printf("请输入您要制作的充值卡数量:"); scanf("%d", &num); printf("请输入您要制作的充值卡积分:"); scanf("%d", &point); sasql_init(); sasql_OnlineCost_add(cost, num, point); sasql_close(); } #endif exit(0); break; case 'm': #ifdef _OLDPS_TO_MD5PS sasql_init(); sasql_OldpsToMd5ps(); sasql_close(); #endif exit(0); break; case 't': { sasql_init(); sasql_TransOnlineCost(); sasql_close(); exit(0); break; } case 'd': { int date; printf("输入时间:"); scanf("%d", &date); sasql_init(); if(date >= 0){ sasql_CleanCdkey(date); }else{ sasql_CleanLockCdkey(); } sasql_close(); exit(0); } break; case 'n': nice(atoi( optarg )); break; default: log( "不能读懂选项 %c\n" , c ); exit(0); } } } double time_diff(struct timeval subtrahend, struct timeval subtractor); int passwd = 0; void dump() { void *array[10]; size_t size; char **strings; size_t i; size = backtrace (array, 10); strings = backtrace_symbols (array, size); printf ("Obtained %zd stack frames.\n", size); for (i = 0; i < size; i++){ logerr(strings[i]); printf ("\n"); } free (strings); } void sigshutdown( int number) { char buff[256]; if( number == 0 ){ printf( "\n\n\nGMSV正常关闭\n" ); }else if( number == 2 ){ printf( "\n\n\nGMSV被CTRL+C手动中断\n" ); }else{ sprintf( buff, "以下是主要错误,必须向我们提交的错误\n"); logerr(buff); dump(); } signal(SIGINT , SIG_IGN ); signal(SIGQUIT, SIG_IGN ); signal(SIGILL, SIG_IGN ); signal(SIGTRAP, SIG_IGN ); signal(SIGIOT, SIG_IGN ); signal(SIGBUS, SIG_IGN ); signal(SIGFPE, SIG_IGN ); signal(SIGKILL, SIG_IGN ); signal(SIGSEGV, SIG_IGN ); signal(SIGPIPE, SIG_IGN ); signal(SIGTERM, SIG_IGN ); log("得到一个信号! 异常中断......\n" ); writeFamily(familydir); writeFMPoint(fmpointdir); writeFMSMemo(fmsmemodir); #ifdef _ANGEL_SUMMON saveMissionTable(); #endif exit(1); } void signalset( void ) { // CoolFish: Test Signal 2001/10/26 printf("\n开始获取信号..\n"); printf("SIGINT:%d\n", SIGINT); printf("SIGQUIT:%d\n", SIGQUIT); printf("SIGFPE:%d\n", SIGILL); printf("SIGTRAP:%d\n", SIGTRAP); printf("SIGIOT:%d\n", SIGIOT); printf("SIGBUS:%d\n", SIGBUS); printf("SIGFPE:%d\n", SIGFPE); printf("SIGKILL:%d\n", SIGKILL); printf("SIGSEGV:%d\n", SIGSEGV); printf("SIGPIPE:%d\n", SIGPIPE); printf("SIGTERM:%d\n", SIGTERM); signal( SIGINT , sigshutdown ); signal( SIGQUIT, sigshutdown ); signal( SIGILL, sigshutdown ); signal( SIGTRAP, sigshutdown ); signal( SIGIOT, sigshutdown ); signal( SIGBUS, sigshutdown ); signal( SIGFPE, sigshutdown ); signal( SIGKILL, sigshutdown ); signal( SIGSEGV, sigshutdown ); signal( SIGPIPE, SIG_IGN ); signal( SIGTERM, sigshutdown ); } int main( int argc , char **argv ) { /* #define cpuid(in,a,b,c,d)\ asm("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in)); unsigned long eax,ebx,ecx,edx; cpuid(0,eax,ebx,ecx,edx); printf("%08x %08lx %08lx %08lx %08lx\n",0,eax,ebx,ecx,edx); */ srand((int)time(0)); parseOpts( argc, argv ); signalset(); // Nuke +1 1012: Loop counter int counter1 = 0; int counter2 = 0; int counter3 = 0; int counter4 = 0; int counter5 = 0; int counter6 = 0; //signal(SIGUSR1, sigusr1); log_rotate_interval = 3600 * 24 * 7; Lock_Init(); // Arminius 7.17 memory lock UNlockM_Init(); if(readConfig( "acserv.cf" )<0){ log( "无法在当前目录里读取 acserv.cf .\n" ); exit(1); } #ifdef _SASQL if(sasql_init()==FALSE){ exit(1); } #ifdef _SQL_BACKGROUND sasql_online(NULL,NULL,NULL,NULL,3); #endif #endif log( "读取数据目录\n" ); dbRead( dbdir ); #ifdef _FAMILY log("读取 家族庄园\n"); readFMSMemo(fmsmemodir); log("读取 家族留言\n"); readFMPoint(fmpointdir); log("读取 家族目录\n"); readFamily(familydir); #endif log( "准备 档案目录\n" ); prepareDirectories( chardir ); log( "准备 日志目录\n" ); prepareDirectories( logdir ); log( "准备 邮件目录\n" ); prepareDirectories( maildir ); #ifdef _SLEEP_CHAR prepareDirectories( sleepchardir ); log( "准备 睡眠档案目录\n" ); #endif /* 凶引匀化月丢□伙毛 心仇戈 */ if( readMail(maildir) < 0 ){ log( "不能初始化邮件\n" ); exit(1); } /* TCPSTRUCT 毛赓渝祭 */ while( 1 ){ int tcpr; if( ( tcpr = tcpstruct_init( NULL , port , 0 , CHARDATASIZE * 16 * MAXCONNECTION , 1 /* DEBUG */ ) ) < 0 ){ log( "不能监听TCP端口,错误代码: %d, 请稍等...\n", tcpr ); sleep( 10 ); }else{ break; } } saacproto_InitServer( netWrite , CHARDATASIZE ); /* { struct sigaction s,os; bzero( &s, sizeof(s)); s.sa_handler = sighandle; s.sa_flags = SA_NOMASK; sigaction( SIGTERM, &s, &os ); bzero( &s, sizeof(s)); s.sa_handler = sighandle; s.sa_flags = SA_NOMASK; sigaction( SIGINT, &s, &os ); bzero( &s, sizeof( s )); s.sa_handler = SIG_IGN; s.sa_flags = SA_NOMASK; sigaction( SIGPIPE, &s, &os ); } */ #ifdef _AC_SEND_FM_PK // WON ADD 庄园对战列表储存在AC load_fm_pk_list(); #endif #ifdef _ACFMPK_LIST FMPK_LoadList(); #endif #ifdef _ALLDOMAN LOAD_herolist(); // Syu ADD 排行榜NPC #endif #ifdef _ANGEL_SUMMON initMissionTable(); #endif log( "\n服务端版本: <%s>\n" , SERVER_VERSION ); printf( "注: AllBlue's在此说明.我们发布免费服务端。严禁商业用途。\n" ); log( "\n开始工作...\n" ); // signal(SIGUSR1,sigusr1); // Arminius 7.20 memory lock int itime=0; while(1){ int newti,i; static time_t main_loop_time; sys_time = time(NULL); #ifdef _LOTTERY_SYSTEM char todayaward[256]="-1,-1,-1,-1,-1,-1,-1"; { if(lotterysystem>0){ struct tm *p; p=localtime(&sys_time); /*取得当地时间*/ static BOOL lottery = FALSE; if( lottery == FALSE){ if((p->tm_mday % lotterysystem) == 0){ if(p->tm_hour == 0){ int award[7]; int i,j; for(i=0;i<7;i++){ award[i]=rand() % 36+1; for(j=0;jtm_hour != 0){ lottery = FALSE; } } } } #endif if( main_loop_time != sys_time){ main_loop_time = time(NULL); counter1++; counter2++; counter3++; counter4++; counter5++; counter6++; if( counter6 > 600 ) // 300( -> 60) { readConfig( "acserv.cf" ); counter6 = 0; } //andy add 2002/06/20 UNlockM_UnlockPlayer(); #ifdef _ANGEL_SUMMON checkMissionTimelimit(); #endif // Nuke *1 1012 if( counter1 > Total_Charlist ){ counter1=0; char *c = ctime( &main_loop_time ); if( c ){ struct timeval st,et; log( "\nTIME:%s\n",c ); gettimeofday( &st,NULL); dbFlush(dbdir); gettimeofday( &et,NULL); log( "Flushed db(%fsec)\n", time_diff(et,st) ); log( "档案表列总数:%d NG:%d\n", total_ok_charlist, total_ng_charlist ); } } // Nuke **1 1012 //if( ( counter % 600 ) == 0 ){ if( counter2 > Expired_mail ){ counter2=0; struct timeval st,et; gettimeofday( &st,NULL); expireMail(); gettimeofday( &et,NULL); log( "过期邮件(%fsec)\n", time_diff(et,st) ); } #ifdef _FAMILY #ifdef _DEATH_FAMILY_LOGIN_CHECK //if ((counter % 300) == 0) // 300( -> 60) if ((counter4 % 1800) == 0) // 3hr( -> 1min) { counter4=0; struct timeval st, et; time_t t1; gettimeofday(&st, NULL); time(&t1); delovertimeFMMem(t1); gettimeofday(&et, NULL); log("Del Family or Member (%fsec)\n", time_diff(et, st)); } #endif if( counter5 > Write_Family ) // 300( -> 60) { counter5=0; struct timeval st, et; gettimeofday(&st, NULL); writeFamily(familydir); writeFMPoint(fmpointdir); writeFMSMemo(fmsmemodir); gettimeofday(&et, NULL); log("记录家族(%fsec)\n", time_diff(et, st)); } #endif } newti = tcpstruct_accept1(); if( newti >= 0 ){ log( "同意: %d\n" , newti ); gs[newti].use = 1; } for(i=0;i 0 ){ char debugfun[256]; buf[l]=0; if( saacproto_ServerDispatchMessage( i , buf, debugfun)<0){ printf("buf:%s;%d\n", buf, strlen(buf)); char token[256]; char tmp[256]; struct tm now; time_t timep; time(&timep); memcpy(&now, localtime(&timep), sizeof(now)); sprintf(tmp, "%02d:%02d:%02d", now.tm_hour, now.tm_min, now.tm_sec); sprintf(token, "[%s]GMSV(%s) 消息:%s\n", tmp, gs[i].name, debugfun); logerr(token); // Nuke start //if(strlen(debugfun)>0){ //logout_game_server(i);// avoid the shutdown the gmsv ttom //} } } else if( l == TCPSTRUCT_ETOOLONG ){ char token[256]; sprintf(token, "很长:%d 服务器名:%s\n", i , gs[i].name ); logerr(token); logout_game_server( i ); } else if( l < 0 ){ log( "关闭:%d 服务器名:%s\n", i , gs[i].name ); logout_game_server(i); } else if( l == 0 ){ ; } } } } return 0; } double time_diff(struct timeval subtrahend, struct timeval subtractor) { return( (subtrahend.tv_sec - subtractor.tv_sec) + (subtrahend.tv_usec - subtractor.tv_usec ) / (double)1E6 ); } /* 夫弘及夫□ □玄市它件玄毛 月[ 云卅元凛渝及手及反允屯化及夫弘白央奶伙互云卅元卞卅月方丹卞允月[ 仇及酷 反醒侬及瑕互云云仁卅月互} 匹奶件正□田伙毛 凳仄化手 暹屺分[ */ int get_rotate_count(void ) { int a; unsigned int t = (unsigned int ) time(NULL); a = ( t / log_rotate_interval ) * log_rotate_interval; return a; } int tcpstruct_init( char *addr , int p , int timeout_ms , int mem_use , int db ) { mbsize = mem_use / sizeof( struct membuf ); mbuse =0; mb_finder = 0; mb = ( struct membuf * ) calloc( 1, mbsize * sizeof(struct membuf )); if( mb == NULL ) return TCPSTRUCT_ENOMEM; bzero( mb , mbsize * sizeof( struct membuf )); con = ( struct connection *) calloc( 1, MAXCONNECTION * sizeof( struct connection )); if( con == NULL ){ free( mb ); return TCPSTRUCT_ENOMEM; } else { int i; for(i=0;i= 0 && con[i].closed_by_remote ==0 ){ FD_SET( con[i].fd , & rfds ); FD_SET( con[i].fd , & wfds ); FD_SET( con[i].fd , & efds ); int j = 1,k; if( (float)(((float)getFreeMem()/(CHARDATASIZE * 16 * MAXCONNECTION))) > 0.10 ){ t = select_timeout; sret = select( con[i].fd+1, & rfds , (fd_set*)NULL, & efds , &t); if( sret > 0 ) { if( ( con[i].fd >= 0 ) && FD_ISSET( con[i].fd , &rfds ) ){ int fr = getFreeMem(); int rr , readsize ; if( fr <= 0 ) continue; memset( tmpbuf, 0, sizeof( tmpbuf)); if( fr > sizeof(tmpbuf ) ){ readsize = sizeof( tmpbuf); } else { readsize = fr - 1; } rr = read( con[i].fd , tmpbuf , readsize ); if( rr <= 0 ){ con[i].closed_by_remote = 1; } else { appendReadBuffer( i , tmpbuf , rr ); #ifdef _DEBUG printf("读取内容:%s\n",tmpbuf); #endif } } } if( (float)(((float)getFreeMem()/(CHARDATASIZE * 16 * MAXCONNECTION))) > 0.50 ){ j = 2; }else if( (float)(((float)getFreeMem()/(CHARDATASIZE * 16 * MAXCONNECTION))) > 0.40 ){ j = 3; }else if( (float)(((float)getFreeMem()/(CHARDATASIZE * 16 * MAXCONNECTION))) > 0.30 ){ j = 4; }else if( (float)(((float)getFreeMem()/(CHARDATASIZE * 16 * MAXCONNECTION))) > 0.20 ){ j = 5; } } for(k=0; k < j; k++){ t = select_timeout; sret = select( con[i].fd+1, (fd_set*)NULL, &wfds, (fd_set*)NULL , &t); if( sret > 0 ) { if( ( con[i].fd >= 0 ) && FD_ISSET( con[i].fd , &wfds )){ char send_buf[4096]; memset( send_buf, 0, sizeof( send_buf)); int l = consumeMemBufList( con[i].mbtop_wi ,send_buf, sizeof(send_buf),0 , 1 ); if(l>0){ int rr = write( con[i].fd , send_buf , l ); if( rr < 0 ){ con[i].closed_by_remote = 1; } else { #ifdef _DEBUG printf("发送内容:%s\n",send_buf); #endif consumeMemBufList( con[i].mbtop_wi , send_buf, l, 1 , 0 ); } } } } } } } for( i=0; i0 to avoid signal interrupt in select if( (asret>0) && FD_ISSET( mainsockfd , & rfds )){ struct sockaddr_in c; int len , newsockfd; int newcon; bzero( &c , sizeof( c )); len = sizeof( c ); fprintf( stderr, "i can accept " ); newcon = findregBlankCon( ); if( newcon < 0 ) continue; newsockfd = accept( mainsockfd, (struct sockaddr*)&c , &len ); #ifdef _IP_VIP char tempIp[20]; strcpy(tempIp,inet_ntoa(c.sin_addr)); for (k=0;k<5;k++) { if (strcmp( tempIp, myip[i]) != 0) { num++; } } if(num >= 5){ log( "拒绝: %d IP:[%s] 没有登记\n" , newsockfd ,tempIp); tcpstruct_close(mainsockfd); continue; } log( "接受: %d IP:[%s]\n" , newsockfd ,tempIp); #else log( "接受: %d\n" , newsockfd); #endif if( newsockfd < 0 ){ unregMemBuf( newcon ); continue; } set_nodelay( newsockfd ); con[newcon].fd = newsockfd; memcpy( &con[newcon].remoteaddr , &c ,sizeof(c)); tis[accepted] = newcon; accepted ++; } } return accepted; } int tcpstruct_close( int ti ) { if( ti < 0 || ti >= MAXCONNECTION )return TCPSTRUCT_EINVCIND; if( con[ti].use == 0 ){ return TCPSTRUCT_ECLOSEAGAIN; } close( con[ti].fd ); con[ti].use = 0; con[ti].fd = -1; /* 伉旦玄毛凶升匀化蝈 毛弁伉失允月 */ consumeMemBufList( con[ti].mbtop_ri , NULL, mbsize * sizeof( mb[0].buf ), 1, 0 ); consumeMemBufList( con[ti].mbtop_wi , NULL, mbsize * sizeof( mb[0].buf ), 1, 0 ); unregMemBuf( con[ti].mbtop_ri ); unregMemBuf( con[ti].mbtop_wi ); con[ti].mbtop_ri = -1; con[ti].mbtop_wi = -1; return OK; } /* 心仇戈手及互手丹卅仁化}仄井手 remoteclose 分匀凶日 -1 毛井尹允 */ int tcpstruct_read( int ti , char *buf , int len ) { int l; if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 ) return TCPSTRUCT_EINVCIND; l = consumeMemBufList( con[ti].mbtop_ri , buf , len , 1 , 1); if( l == 0 && con[ti].closed_by_remote ) return TCPSTRUCT_EREADFIN; return l; } /* 1垫毛方心仇戈[ int kend : 1卅日垫 及 \n 毛诮允 int kend_r : 1卅日垫 及 \r 手诮允(丐木壬) 心仇戈手及互手丹卅仁化}井勾 remote closed 分匀凶日-1毛井尹允 // Nuke Read 1 line if kend==1 then delete \n at the tail if kend_r== 1 then delete \r at the tail (if any) if no data read, it means 'remote closed' then return -1 */ int tcpstruct_readline( int ti , char *buf , int len , int kend , int kend_r ) { int l; int minus = 0; if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 ) return TCPSTRUCT_EINVCIND; l = getLineReadBuffer( ti , buf , len ); if( l == 0 ){ if( con[ti].closed_by_remote ){ return TCPSTRUCT_EREADFIN; } else { return 0; } } if( kend ){ if( buf[l-1]=='\n' ){ buf[l-1] = 0; minus =-1; } } if( kend_r ){ if( buf[l-1]=='\r' ){ buf[l-1] = 0; minus = -1; } if( buf[l-2]=='\r' ){ buf[l-2] = 0; minus = -2; } } return l + minus; } int tcpstruct_readline_chop( int ti , char *buf, int len ) { return tcpstruct_readline( ti , buf , len , 1,1); } int tcpstruct_write( int ti , char *buf , int len ) { if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 ) return TCPSTRUCT_EINVCIND; return appendWriteBuffer( ti , buf , len ); } int tcpstruct_connect( char *addr , int port ) { int newti ; int s, r; struct sockaddr_in svaddr; struct hostent *he; s = socket( AF_INET, SOCK_STREAM , 0 ); if(s<0)return -2; bzero( &svaddr , sizeof( svaddr )); svaddr.sin_family = AF_INET; svaddr.sin_port = htons( port ); if( inet_aton( addr, &svaddr.sin_addr ) == 0 ){ he = gethostbyname( addr ); if( he == NULL ){ return TCPSTRUCT_EHOST; } memcpy( & svaddr.sin_addr.s_addr , he->h_addr , sizeof( struct in_addr)); } r = connect( s , ( struct sockaddr*)&svaddr,sizeof(svaddr)); if( r < 0 ){ return TCPSTRUCT_ECONNECT; } set_nodelay( s ); newti = findregBlankCon( ); if( newti < 0 ){ fprintf( stderr , "连接失败: newti:%d\n", newti ); return TCPSTRUCT_ECFULL; } con[newti].fd = s; memcpy( & con[newti].remoteaddr , &svaddr , sizeof( struct sockaddr_in)); return newti; } static int appendReadBuffer( int index , char *data , int len ) { int top; top = con[index].mbtop_ri; for(;;){ int nextind = mb[top].next; if( nextind == -1 ) break; top = nextind; } return appendMemBufList( top , data , len ); } static int appendWriteBuffer( int index , char *data , int len ) { int top; top = con[index].mbtop_wi; for(;;){ int nextind = mb[top].next; if( nextind == -1 ) break; top = nextind; } return appendMemBufList( top , data , len ); } static int appendMemBufList( int top , char *data , int len ) { int fr = getFreeMem( ); int rest = len; int data_topaddr = 0; if( len >= fr ){ /* FILE *fp; if( (fp=fopen( "badsysinfo.txt", "a+")) != NULL ){ fprintf( fp, "appendMemBufList() len:%d / fr:%d err !! \n", len, fr); fclose( fp); } */ //andy_log log( "appendMemBufList() len:%d / fr:%d err !! \n", len, fr); return -1; } data[len] = 0; for(;;){ int blanksize = sizeof( mb[0].buf ) - mb[top].len; int cpsize = ( rest <= blanksize ) ? rest : blanksize; memcpy( mb[top].buf + mb[top].len , data + data_topaddr , cpsize ); mb[top].len += cpsize; if( rest <= blanksize ){ return len; } else { int newmb; rest -= cpsize; data_topaddr += cpsize; if( (newmb = findregBlankMemBuf( ) ) == TCPSTRUCT_EMBFULL ){ FILE *fp; if( (fp=fopen( "badsysinfo.txt", "a+")) != NULL ){ fprintf( fp, "find newmb == TCPSTRUCT_EMBFULL err data:%s !!\n", data); fclose( fp); } log( "find newmb == TCPSTRUCT_EMBFULL err data:%s !!\n", data); } mb[top].next = newmb; top = mb[top].next; } } return TCPSTRUCT_EBUG; } static int consumeMemBufList( int top , char *out , int len , int consumeflag , int copyflag ) { int total = 0; int top_store = top; for(;;){ int cpsize; if( top == -1 ) break; cpsize = ( mb[top].len <= ( len - total) ) ? mb[top].len : ( len - total ); if( copyflag ) memcpy( out + total , mb[top].buf , cpsize ); total += cpsize; if( consumeflag ){ mb[top].len -= cpsize; if( mb[top].len > 0 ){ /* 勾井中反凶仄化卅中及匹memmove */ memmove( mb[top].buf , mb[top].buf + cpsize , sizeof( mb[top].buf ) - cpsize ); } } top = mb[top].next; if( total == len ){ break; } } if( consumeflag ){ /* 卅互今互0卞卅匀化月卅日荸 [匹手 赓及支勾反荸 仄卅中冗 */ top = mb[top_store].next; for(;;){ if( top == -1 )break; if( mb[top].len == 0 ){ int prev; mb[top_store].next = mb[top].next; prev = top; top = mb[top].next; unregMemBuf( prev ); } else { top = mb[top].next; } } } return total; } static int getLineReadBuffer( int index , char *buf, int len ) { int top = con[index].mbtop_ri; int ti = 0 , breakflag = 0; for(;;){ int i; int l = mb[top].len; if( top == -1 )break; for( i=0 ; i < l ; i++){ if( mb[top].buf[i] == '\n' ){ breakflag = 1; break; } ti ++; } if( breakflag )break; top = mb[top].next; } if( ti > len ){ /* 1垫互卅互允亢月[ 卅巨仿□毛井尹六 */ return TCPSTRUCT_ETOOLONG; } /* 垫互敦岳仄化卅中 */ if( breakflag == 0 ){ return 0; } return consumeMemBufList( con[index].mbtop_ri , buf , ti+1 , 1 , 1 ); } /* 心仇户月 赢今毛忒允 int index : con index return: 反巨仿□ 0动晓及桦宁反 read 仄化手方中赢今[ mbsize 井日mbuse 毛娄中化扔奶术毛井仃月分仃[ 仇引井中芴曰及坌反 骰允月[公氏卅称井中袄卞仇分歹日卅仁化手第[ */ static int getFreeMem( void ) { return ( mbsize - mbuse ) * sizeof( mb[0].buf ); } /* membuf 及坞五毛茧仄分允[ return : 心勾井匀凶日 >=0 匹 index. 心勾井日卅井匀凶日 腹绸及午五卞反 mb_finder 毛勾井丹[ 仇木匹腹绸仄化} 卞reg允月[ */ static int findregBlankMemBuf( void ) { int i; for(i=0;i= mbsize || mb_finder < 0 ) mb_finder = 0; if( mb[mb_finder].use == 0 ){ mb[mb_finder].use = 1; mb[mb_finder].len = 0; mb[mb_finder].next = -1; mbuse ++; return mb_finder; } } return TCPSTRUCT_EMBFULL; } /* mb 毛荸 允月 */ static int unregMemBuf( int index ) { mb[index].use=0; mb[index].next = -1; mb[index].len = 0; mbuse --; return OK; } static int findregBlankCon( void ) { int i; // Nuke changed 0->1 //for(i=0;i= MAXMISSIONTABLE) break; } fclose( fp); log("..成功! \n"); return TRUE; } int saveMissionTable( void ) { FILE *fp; char onedata[1024]; int index =0; fp = fopen( MISSIONFILE, "w"); if( !fp ) { log("\n打开精灵召唤错误!!!! \n"); //return false; } log("\n保存精灵召唤..."); for( index =0; index < MAXMISSIONTABLE; index++) { if( missiontable[index].angelinfo[0] == '\0' ) continue; sprintf( onedata, "%s,%s,%d,%d,%d,%d\n", missiontable[index].angelinfo, missiontable[index].heroinfo, missiontable[index].mission, missiontable[index].flag, missiontable[index].time, missiontable[index].limittime ); fputs( onedata, fp); } fclose( fp); log("..成功! \n"); return TRUE; } void delMissionTableOnedata( int index) { int gi; log("\n删除精灵召唤:%d:%s:%s \n", index, missiontable[index].angelinfo, missiontable[index].heroinfo); if( index <0 || index >=MAXMISSIONTABLE) return; strcpy( missiontable[index].angelinfo, ""); strcpy( missiontable[index].heroinfo, ""); missiontable[index].mission = 0; missiontable[index].flag = MISSION_NONE; missiontable[index].time = 0; missiontable[index].limittime = 0; for( gi=0; gi missiontable[index].time + ANSWERTIME*60*60 ) { delMissionTableOnedata( index);// 删 } // 等待领奖完成 limittime小时 else if( ( missiontable[index].flag == MISSION_DOING || missiontable[index].flag == MISSION_HERO_COMPLETE ) && ( sys_time > (missiontable[index].time + missiontable[index].limittime*60*60)) ) { char buf[1024]; int gi; // 改TIMEOVER log("精灵召唤及领奖时间过:%d ", index); missiontable[index].flag = MISSION_TIMEOVER; missiontable[index].time = time(NULL); missiontable[index].limittime = BOUNDSTIME; sprintf( buf, "%d|%s|%s|%d|%d|%d|%d ", index, missiontable[index].angelinfo, missiontable[index].heroinfo, missiontable[index].mission, missiontable[index].flag, missiontable[index].time, missiontable[index].limittime ); for( gi=0; gi missiontable[index].time + BOUNDSTIME*60*60 ) { // log(" 领奖时间过:%d ", index); // delMissionTableOnedata( index);// 删 //} // 资料保留时间(BOUNDSTIME小时) else if( missiontable[index].flag == MISSION_TIMEOVER && sys_time > missiontable[index].time + BOUNDSTIME*60*60 ) { log(" 保留时间过:%d ", index); delMissionTableOnedata( index);// 删 } } saveMissionTable(); #ifdef _SAVE_ZIP if (SAVEZIP > 0) savezipfile(); #endif lastcheck = sys_time; } #endif void logerr(char *token) { char tmp[256]; struct tm now; time_t timep; time(&timep); memcpy(&now, localtime(&timep), sizeof(now)); sprintf(tmp, "%04d-%02d-%02d.log", now.tm_year+1900, now.tm_mon+1, now.tm_mday); FILE *fp=fopen(tmp,"a+"); fwrite(token, strlen(token), 1, fp); fclose(fp); printf( token ); } #ifdef _SAVE_ZIP void savezipfile( void ) { time_t timep; time(&timep); struct tm * ptm; int y,m,d; timep = time(NULL); ptm = localtime(&timep); y = ptm->tm_year +1900; m = ptm->tm_mon+1; d = ptm->tm_mday; char buf[256]; sprintf( buf, "%d-%d-%d.zip",y,m,d); if (access(buf,W_OK) == 0) return;//文件存在 sprintf( buf, "zip -q -r %d-%d-%d.zip char char_sleep data db lock log mail pklist race&",y,m,d); log("备份档案..."); system(buf); log("成功!\n"); return; } #endif