main.c
上传用户:qys8201
上传日期:2021-12-11
资源大小:978k
文件大小:39k
源码类别:

模拟服务器

开发平台:

C/C++

  1. #define _MAIN_C_
  2. #include "main.h"
  3. #include "util.h"
  4. #include "mail.h"
  5. #include "db.h"
  6. #include "saacproto_util.h"
  7. #include "saacproto_serv.h"
  8. // CoolFish: Family 2001/5/9
  9. #include "acfamily.h"
  10. #include "version.h"
  11. #ifdef _SEND_EFFECT   // WON ADD 送下雪、下雨等特效 
  12. #include "recv.h"
  13. #endif
  14. #include "char.h"
  15. #ifdef _SASQL
  16. #include "sasql.h"
  17. #endif
  18. #include <stdio.h> 
  19. #include <time.h> 
  20. #include <signal.h>
  21. #include <sys/types.h>
  22. #include <time.h>
  23. #include <sys/time.h>
  24. #include <errno.h>
  25. #include <sys/wait.h>
  26. #include <getopt.h>
  27. #include <stdio.h>
  28. #include <malloc.h>
  29. #include <strings.h>
  30. #include <string.h>
  31. #include <unistd.h>
  32. #include <netdb.h>
  33. #include <errno.h>
  34. #include <sys/socket.h>
  35. #include <netinet/in.h>
  36. #include <arpa/inet.h>
  37. #include <time.h>
  38. #include <fcntl.h>
  39. #include <netinet/tcp.h>
  40. #include "lock.h"
  41. #define BACKLOGNUM 5
  42. int worksockfd;
  43. struct membuf
  44. {
  45.     int use;
  46.     char buf[512];
  47. //    char buf[1024*128];
  48.     int len;
  49.     int next;
  50. };
  51. struct connection
  52. {
  53.     int use;    
  54.     int fd;       
  55.     int mbtop_ri;
  56.     int mbtop_wi;
  57.     struct sockaddr_in remoteaddr;
  58.     int closed_by_remote;
  59. };
  60. struct membuf *mb;
  61. int mbsize;
  62. int mbuse ;
  63. int cpuuse;
  64. int mainsockfd;             /* accept 及  域娄醒卞中木月 */
  65. struct sockaddr_in localaddr;       /* bind 允月失玉伊旦 */
  66.     
  67. struct connection *con;        /* 戊生弁扑亦件     */
  68. static int mb_finder=0;              /* mb及坞五毛腹绸允月凶户及
  69.                                腹绸玄永皿及匏  筏盛迕 */
  70. // WON FIX
  71. //char tmpbuf[65536];
  72. char tmpbuf[1024*32];
  73. //char tmpbuf[65536*3];         /* read迕 */
  74. struct timeval select_timeout;
  75. time_t sys_time =0; // Robin add
  76. extern gmsv gs[MAXCONNECTION];
  77. int tcpstruct_init( char *addr, int port, int timeout_ms, int mem_use, int deb);
  78. int tcpstruct_accept1( void );
  79. int tcpstruct_accept( int *tis , int ticount );
  80. int tcpstruct_close( int ti );
  81. int tcpstruct_read( int ti , char *buf , int len );
  82. int tcpstruct_readline( int ti , char *buf , int len ,int k ,int r);
  83. int tcpstruct_readline_chop( int ti , char *buf, int len );
  84. int tcpstruct_write( int ti , char *buf , int len );
  85. int tcpstruct_countmbuse( void );
  86. int tcpstruct_connect( char *addr , int port );
  87. void set_nodelay( int sock );
  88. #define OK     0        /* 岳   */
  89. #define TCPSTRUCT_ENOMEM -1       /* malloc 撩   */
  90. #define TCPSTRUCT_ESOCK -2        /* socket 撩   */
  91. #define TCPSTRUCT_EBIND -3        /* bind 撩   */
  92. #define TCPSTRUCT_ELISTEN -4      /* listen 撩   */
  93. #define TCPSTRUCT_EBUG -6         /* 田弘匹丐月 */
  94. #define TCPSTRUCT_EINVCIND -7     /* con尺及index互云井仄中方 */
  95. #define TCPSTRUCT_EREADFIN -8     /* read 允月犯□正互卅仁化 closed by remote */
  96. #define TCPSTRUCT_EHOST -9        /* gethostbyname 撩   */
  97. #define TCPSTRUCT_ECONNECT -10    /* connect 撩   */
  98. #define TCPSTRUCT_ECFULL -11      /* con 互中匀天中 */
  99. #define TCPSTRUCT_ETOOLONG -12    /* 垫互卅互允亢 */
  100. #define TCPSTRUCT_EMBFULL -13     /* mb 互中匀天中  */
  101. #define TCPSTRUCT_ECLOSEAGAIN -14 /* close 互2荚今木凶 */
  102. int port;               /* 必□丞扔□田□互涛粮仄化仁月禾□玄 */
  103. int Total_Charlist;
  104. int Expired_mail;
  105. int Del_Family_or_Member;
  106. int Write_Family;
  107. // Nuke start
  108. char *chartime()
  109. {
  110.     static char buf[80];
  111.     time_t t;
  112.     t=time(0);
  113.     strcpy(buf,ctime(&t));
  114.     buf[strlen(buf)-1]=0;
  115.     return(buf);
  116. }
  117. #ifdef _ANGEL_SUMMON
  118. extern struct MissionTable missiontable[MAXMISSIONTABLE];
  119. static int initMissionTable( void );
  120. int saveMissionTable( void );
  121. void checkMissionTimelimit( void);
  122. #endif
  123. static int initRankTable( void );
  124. /*
  125.   sigaction白弁
  126.  */
  127. void sighandle( int a )
  128. {
  129.   if (a==SIGUSR1) log("sigusr1信号!n");
  130.   log("得到一个信号! 异常中断......n" );
  131.   writeFamily(familydir);
  132.   writeFMPoint(fmpointdir);
  133.   writeFMSMemo(fmsmemodir);
  134. #ifdef _ANGEL_SUMMON
  135. saveMissionTable();
  136. #endif
  137.   exit(1);
  138. }
  139. // Arminius 7.20 memory unlock
  140. void sigusr1(int a)
  141. {
  142.   int i;
  143.   FILE *f;
  144.   char key[4096],buf[4096];
  145.   signal(SIGUSR1, sigusr1);
  146.   
  147.   f = fopen("./unlock.arg", "r");
  148.   if (f) {
  149.     memset(key, 0, 4096);
  150.     fread(key, 4096, 1, f);
  151.     for (i=0; i<strlen(key); i++) if (key[i]=='n') key[i]='';
  152.     switch (key[0]) {
  153.     case 'P': // unlock player
  154.       if (DeleteMemLock(getHash(&key[1]) & 0xff,&key[1],&i)) {
  155.         log("ADM: memunlock: %s success.n", key);
  156.       } else {
  157.         log("ADM: memunlock: %s failed.n", key);
  158.       }
  159.     break;
  160.     case 'S': // unlock server
  161.       DeleteMemLockServer(&key[1]);
  162.       log("ADM: memunlock: %sn", key);
  163.     break;
  164.     case 'C': // check player lock
  165.       GetMemLockState(getHash(&key[1]) & 0xff, &key[1], buf);
  166.       sprintf(key, "echo "%s" > ./sigusr1.result", buf);
  167.       system(key);
  168.     break;
  169. #ifdef _SEND_EFFECT    // WON ADD 送下雪、下雨等特效
  170. case 'E':
  171. log("nAC 向 GS 发送下雪特效!!n");
  172.     SendEffect(&key[1]);
  173. break;
  174. #endif
  175. case 'L':  // Robin 列出所有Server连线
  176. log("nList All Server Conncet!!!!!n");
  177. for( i =0; i <MAXCONNECTION; i++)
  178. if( gs[i].use)
  179. log("n gs[%d] fd:%d name:%s ", i, gs[i].fd, gs[i].name );
  180. break;
  181.   }
  182. log(" sigusr1_over_1 ");
  183. fclose(f);
  184. log(" sigusr1_over_2 ");
  185.   }
  186. }
  187. static int netWrite( int ti , char *buf , int len)
  188. {
  189.     return tcpstruct_write( ti , buf, len );
  190. }
  191. gmsv gs[MAXCONNECTION];
  192. #ifdef _VIP
  193. int login_game_server( int ti , char *svname , char *svpas , int checkvip,
  194.                char *result , int resultlen ,
  195.                char *retdata , int retdatalen )
  196. #else
  197. int login_game_server( int ti , char *svname , char *svpas ,
  198.                char *result , int resultlen ,
  199.                char *retdata , int retdatalen )
  200. #endif
  201. {
  202. #ifndef _VIP
  203. char buff[50];
  204. sprintf(buff,"longzoro-%s-%d",svpass,123);
  205.     if( strcmp( svpas , buff ) == 0 ){
  206. #else
  207. if( strcmp( svpas , svpass ) == 0 ){
  208. #endif
  209.         log( "服务器密码正确 %sn" , svname );
  210.     } else {
  211.         log( "服务器密码错误 %sn" , svname );
  212.         snprintf( result , resultlen , "失败" );
  213.         snprintf( retdata , retdatalen , "密码错误" );
  214.         return 0;
  215.     }
  216. #ifdef _VIP
  217.     if(checkvip==0 || checkvip!=55575556 * 2)
  218.     {
  219.      snprintf( result , resultlen , "failed" );
  220.       snprintf( retdata , retdatalen , "duplicate login" );
  221.       return 0;
  222.     }
  223. #endif
  224.     {
  225.         int i;
  226.         for(i=0;i<MAXCONNECTION;i++){
  227.             if( gs[i].use &&
  228.                 strcmp( gs[i].name , svname ) == 0 ){
  229.                 snprintf( result, resultlen, "failed" );
  230.                 snprintf( retdata , retdatalen, "duplicate login" );
  231.                 return 0;
  232.             } 
  233.         }
  234.     }
  235.     snprintf( gs[ti].name , sizeof(gs[ti].name), "%s" , svname );
  236.   gs[ti].fd = ti;
  237.     snprintf( result , resultlen ,SUCCESSFUL );
  238.     snprintf( retdata , retdatalen , "Nothing special" );
  239.     DeleteMemLockServer(svname); // Arminius 7.31 unlock server
  240.     return 0;
  241. }
  242. int logout_game_server( int ti )
  243. {
  244.     gs[ti].use = 0;
  245. gs[ti].fd = -1;
  246.     gs[ti].name[0] = 0;
  247.     tcpstruct_close( ti );
  248.     return 0;
  249. }
  250. int is_game_server_login( int ti )
  251. {
  252.     return gs[ti].use;
  253. }
  254. static int readConfig( char *path )
  255. {
  256.     char buf[2048];
  257.     FILE *fp;
  258.     fp = fopen( path , "r" );
  259.     if( fp == NULL ){ return -2; }
  260.     while( fgets( buf , sizeof( buf ) , fp )){
  261.         char command[128];
  262.         char param[128];
  263.         chop(buf);
  264.         
  265.         easyGetTokenFromString( buf , 1 , command , sizeof( command ));
  266.         easyGetTokenFromString( buf , 2 , param , sizeof( param ));
  267.         if( strcmp( command , "port" ) == 0 ){
  268.             port = atoi( param );
  269.          log( "端口:%dn",port );
  270.         } else if( strcmp( command , "logdir" ) == 0 ){
  271.             snprintf( logdir , sizeof( logdir) , param );
  272.             log( "日志目录:%sn",logdir );
  273.         } else if( strcmp( command , "chardir" ) == 0 ){
  274.             snprintf( chardir , sizeof( chardir) , param );
  275.             log( "档案目录:%sn",chardir );
  276. #ifdef _SLEEP_CHAR
  277. snprintf( sleepchardir , sizeof( sleepchardir), "%s_sleep", chardir);
  278. log( "睡眠目录:%sn",sleepchardir );
  279. #endif
  280.         } else if( strcmp( command , "pass" ) == 0 ){
  281.          snprintf( svpass , sizeof( svpass ) , param);
  282.             log( "密码:%sn",param );
  283.         } else if( strcmp( command , "dbdir" ) == 0 ){
  284.             snprintf( dbdir , sizeof( dbdir) , param );    
  285.             log( "数据目录:%sn",dbdir );        
  286.         } else if( strcmp( command, "rotate_interval" ) == 0 ){
  287.             log_rotate_interval = atoi( param );
  288.             log( "日志循环间隔:%dn",log_rotate_interval ); 
  289.         } else if( strcmp( command, "maildir" ) == 0 ){
  290.             snprintf( maildir, sizeof( maildir ), param );
  291.             log( "邮件目录:%sn",maildir );
  292. #ifdef _FAMILY
  293.         // CoolFish: Family 2001/5/9
  294.         } else if( strcmp( command, "familydir" ) == 0 ){
  295.             snprintf( familydir, sizeof( familydir ), param );
  296.             log( "家族目录:%sn",familydir );
  297.         } else if( strcmp( command, "fmpointdir" ) == 0 ){
  298.             snprintf( fmpointdir, sizeof( fmpointdir ), param );
  299.             log( "庄园表列:%sn",fmpointdir );
  300.         } else if( strcmp( command, "fmsmemodir" ) == 0 ){
  301.             snprintf( fmsmemodir, sizeof( fmsmemodir ), param );
  302.             log( "家族备份:%sn",fmsmemodir );
  303. #endif
  304.   } else if( strcmp( command , "Total_Charlist" ) == 0 ){
  305.          Total_Charlist = atoi( param );
  306.          log( "更新人物点数间隔:%d秒n",Total_Charlist );
  307.         } else if( strcmp( command , "Expired_mail" ) == 0 ){
  308.          Expired_mail = atoi( param );
  309.          log( "更新过期邮件间隔:%d秒n",Expired_mail );
  310.         } else if( strcmp( command , "Del_Family_or_Member" ) == 0 ){
  311.          Del_Family_or_Member = atoi( param );
  312.          log( "删除家族成员间隔:%d秒n",Del_Family_or_Member );
  313.         } else if( strcmp( command , "Write_Family" ) == 0 ){
  314.          Write_Family = atoi( param );
  315.          log( "更新家族信息间隔:%d秒n",Write_Family );
  316. } else if( strcmp( command , "SameIpMun" ) == 0 ){
  317.          sameipmun = atoi( param );
  318.          if(sameipmun>0){
  319.          log( "同IP允许同时登陆:%d次n",sameipmun );
  320.          }else{
  321.          log( "同IP允许同时登陆:无限制n" );
  322.          }
  323. }
  324.     }
  325.     fclose(fp);
  326.     return 0;
  327. }
  328. static void parseOpts( int argc, char **argv )
  329. {
  330.     int c , option_index;
  331. while(1){
  332.         static struct option long_options[] = {
  333.             {"nice" , 1 , 0 , 'n'},
  334.             {"help" , 0 , 0 , 'h' },
  335.             {"userinfo",0 , 0 , 'i'},
  336.             {"lockuser",0 , 0 , 'l'}
  337.         };
  338.         c = getopt_long( argc , argv , "n:hil" , long_options , &option_index );
  339.         if( c == -1 )break;
  340.         switch( c ){
  341.         case 'h':
  342.             fprintf( stderr ,
  343.                      "使用方法: saac [-h] [-w port] [-w port] ... n"
  344.                      "-h : 显示saac的帮助n"
  345.                      "-w port : 添加一个工作站进程端口n"
  346.                      "Copyright 2006 龙zoro工作室 "
  347.                      "( Longzoro System Supply )n");
  348.             exit(0);
  349.             break;
  350.         case 'i':
  351. #ifdef _SASQL
  352.          sasql_init();
  353.          sasql_craete_userinfo();
  354.          sasql_close();
  355. #endif
  356. exit(0);
  357.             break;
  358.         case 'l':
  359. #ifdef _SASQL
  360.          sasql_init();
  361.          sasql_craete_lock();
  362.          sasql_close();
  363. #endif
  364.          exit(0);
  365.             break;
  366.         case 'n':
  367.          nice(atoi( optarg ));
  368.          break;
  369.         default:
  370.             log( "不能读懂选项 %cn" , c );
  371.             exit(0);
  372.         }
  373.     }
  374. }
  375. double time_diff(struct timeval subtrahend,  struct timeval subtractor);
  376. int main( int argc , char **argv )
  377. {
  378. parseOpts( argc, argv );
  379.     // Nuke +1 1012: Loop counter
  380.     int counter1 = 0;
  381.     
  382.     int counter2 = 0;
  383.     
  384.     int counter3 = 0;
  385.     
  386.     int counter4 = 0;
  387.     signal(SIGUSR1, sigusr1);
  388.     log_rotate_interval = 3600 * 24 * 7;
  389.     Lock_Init(); // Arminius 7.17 memory lock
  390. UNlockM_Init();
  391.     
  392.     if(readConfig( "acserv.cf" )<0){
  393.         log( "无法在当前目录里读取 acserv.cf .n" );
  394.         exit(1);
  395.     }
  396. #ifdef _SASQL
  397.     sasql_init();
  398. #endif
  399.     log( "读取数据目录n" );
  400.     dbRead( dbdir );
  401. #ifdef _FAMILY
  402.     log("读取 家族庄园n");
  403.     readFMSMemo(fmsmemodir);
  404.     log("读取 家族留言n");
  405.     readFMPoint(fmpointdir);
  406.     log("读取 家族目录n");
  407.     readFamily(familydir);
  408. #endif
  409.     log( "准备 档案目录n" );
  410.     prepareDirectories( chardir );
  411.     log( "准备 日志目录n" );
  412.     prepareDirectories( logdir );
  413.     log( "准备 邮件目录n" );
  414.     prepareDirectories( maildir );
  415. #ifdef _SLEEP_CHAR
  416.     prepareDirectories( sleepchardir );
  417.     log( "准备 睡眠档案目录n" );
  418. #endif
  419.     /* 凶引匀化月丢□伙毛  心仇戈 */
  420.     if( readMail(maildir) < 0 ){
  421.         log( "不能初始化邮件n" );
  422.         exit(1);
  423. }
  424.     /* TCPSTRUCT 毛赓渝祭 */
  425.     {
  426.         int tcpr;
  427.         if( ( tcpr = tcpstruct_init( NULL , port , 0 ,
  428. CHARDATASIZE * 16 * MAXCONNECTION , 1 /* DEBUG */ ) ) < 0 ){
  429.             log( "不能开启TCP: %dn", tcpr );
  430.             return 1;
  431.         }
  432.     }
  433.     saacproto_InitServer( netWrite , CHARDATASIZE );
  434.     {
  435.         struct sigaction s,os;
  436.         
  437.         bzero( &s, sizeof(s));
  438.         s.sa_handler = sighandle;
  439.         s.sa_flags = SA_NOMASK;
  440.         sigaction( SIGTERM,  &s, &os );
  441.         bzero( &s, sizeof(s));
  442.         s.sa_handler = sighandle;
  443.         s.sa_flags = SA_NOMASK;
  444.         sigaction( SIGINT,  &s, &os );
  445.         bzero( &s, sizeof( s ));
  446.         s.sa_handler = SIG_IGN;
  447.         s.sa_flags = SA_NOMASK;
  448.         sigaction( SIGPIPE, &s, &os );
  449.     }
  450. #ifdef _AC_SEND_FM_PK  // WON ADD 庄园对战列表储存在AC
  451. load_fm_pk_list();
  452. #endif
  453. #ifdef _ACFMPK_LIST
  454. FMPK_LoadList();
  455. #endif
  456. #ifdef _ALLDOMAN
  457. LOAD_herolist();  // Syu ADD 排行榜NPC
  458. #endif
  459. #ifdef _ANGEL_SUMMON
  460. initMissionTable();
  461. #endif
  462. #ifdef _VIP
  463. log( "n服务端版本: <%s 会员版>n" , SERVER_VERSION );
  464. #else
  465. log( "n服务端版本: <%s 普通版>n" , SERVER_VERSION );
  466. #endif
  467. log( "n服务端编译完成时间:%s %s by 龙zoro工作室n" , __DATE__ , __TIME__ );
  468.     log( "n开始工作...n" );
  469.     signal(SIGUSR1,sigusr1); // Arminius 7.20 memory lock
  470. int itime=0;
  471. while(1){
  472. itime++;
  473. if(itime>cpuuse){
  474. itime=0;
  475. usleep(1);
  476. }
  477.     int newti,i;
  478.     static time_t main_loop_time;
  479. sys_time = time(NULL);
  480. if( main_loop_time != sys_time){
  481.             main_loop_time = time(NULL);
  482.             counter1++;
  483.             counter2++;
  484.             counter3++;
  485.             counter4++;
  486. //andy add 2002/06/20
  487. UNlockM_UnlockPlayer();
  488. #ifdef _ANGEL_SUMMON
  489. checkMissionTimelimit();
  490. #endif
  491.             // Nuke *1 1012
  492.             if( counter1 > Total_Charlist ){
  493.              counter1=0;
  494.                 char *c = ctime( &main_loop_time );
  495.                 if( c ){
  496.                     struct timeval st,et;
  497.                     log( "nTIME:%sn",c );
  498.                     gettimeofday( &st,NULL);
  499.                     dbFlush(dbdir);
  500.                     gettimeofday( &et,NULL);
  501.                     log( "Flushed db(%fsec)n", time_diff(et,st) );
  502.                     log( "档案表列总数:%d NG:%dn",
  503.                          total_ok_charlist, total_ng_charlist );
  504.                 }
  505.             }
  506.             // Nuke **1 1012
  507.             //if( ( counter % 600 ) == 0 ){
  508.             if( counter2 > Expired_mail ){
  509.              counter2=0;
  510.                 struct timeval st,et;
  511.                 gettimeofday( &st,NULL);
  512.                 expireMail();
  513.                 gettimeofday( &et,NULL);
  514.                 log( "过期邮件(%fsec)n", time_diff(et,st) );
  515.             }
  516. #ifdef _FAMILY
  517.             //if ((counter % 300) == 0) // 300( -> 60)
  518.       if( counter4 > Write_Family ) // 300( -> 60)
  519.       {
  520.          counter4=0;
  521.           struct timeval st, et;
  522.           gettimeofday(&st, NULL);
  523.           writeFamily(familydir);
  524.           writeFMPoint(fmpointdir);
  525.           writeFMSMemo(fmsmemodir);
  526.           gettimeofday(&et, NULL);
  527.           log("记录家族(%fsec)n", time_diff(et, st));
  528.       }
  529. #endif
  530.         }
  531.     newti = tcpstruct_accept1();
  532.     if( newti >= 0 ){
  533. log( "同意: %dn" , newti );
  534. gs[newti].use = 1;
  535.     }
  536.         for(i=0;i<MAXCONNECTION;i++){
  537. //         char buf[CHARDATASIZE * 16;
  538.             char buf[CHARDATASIZE];
  539.             int l;
  540.             l = tcpstruct_readline_chop( i , buf , sizeof( buf )- 1);
  541. {
  542.                 if( !gs[i].use )continue;
  543.                 if( l > 0 ){
  544. char debugfun[256];
  545.                     buf[l]=0;
  546.                     if( saacproto_ServerDispatchMessage( i , buf, debugfun)<0){
  547.                         // Nuke start
  548.                         tcpstruct_close(i);// avoid the shutdown the gmsv ttom
  549.                         log( "GMSV(%s) 消息:%sn", gs[i].name, debugfun);
  550.                     }
  551.                 } else if( l == TCPSTRUCT_ETOOLONG ){
  552.                     log( "很长:%d 服务器名::%sn", i , gs[i].name );
  553.                     logout_game_server( i );
  554.                 } else if( l < 0 ){
  555.                     log( "关闭:%d 服务器名:%sn", i , gs[i].name );
  556.                     logout_game_server(i);
  557.                 } else if( l == 0 ){
  558.                     ;
  559.                 }
  560.             }
  561.         }
  562.         {
  563.             static struct timeval tv_loop_store ;
  564.             struct timeval now;
  565.             double dif;
  566.             gettimeofday( &now , NULL );
  567.             dif = time_diff( now, tv_loop_store );
  568.             if( dif > 0.5 ){ // CoolFish 0.1 -> 0.5 2001/5/19
  569.                 //log( "Sl:%f" , dif );
  570.             }
  571.             tv_loop_store = now;
  572.         }
  573.         /* 伐□市□及正奶丞失它玄毛譬屯月[
  574.            正奶丞失它玄仄凶日夫弘毛分仄化伐□市□毛诮仄化仄引丹[
  575.            匹必□丞扔□田□卞  蔽读卞反骚襞允月           */
  576.     }
  577.     return 0;       
  578. }
  579. double
  580. time_diff(struct timeval subtrahend,
  581.           struct timeval subtractor)
  582. {
  583.     return( (subtrahend.tv_sec - subtractor.tv_sec)
  584.             + (subtrahend.tv_usec
  585.             - subtractor.tv_usec  ) / (double)1E6 );
  586. }
  587. /*
  588.   夫弘及夫□  □玄市它件玄毛  月[
  589.   云卅元凛渝及手及反允屯化及夫弘白央奶伙互云卅元卞卅月方丹卞允月[
  590.   仇及酷  反醒侬及瑕互云云仁卅月互}    匹奶件正□田伙毛  凳仄化手
  591.     暹屺分[
  592.   
  593.  */
  594. int get_rotate_count(void )
  595. {
  596.     int a;
  597.     unsigned int t = (unsigned int ) time(NULL);
  598.         
  599.     a = ( t / log_rotate_interval ) * log_rotate_interval;
  600.     
  601.     return a;
  602. }
  603. static int findregBlankMemBuf( void );
  604. static int unregMemBuf( int index );
  605. static int findregBlankCon( void );
  606. static int getFreeMem( void );
  607. static int appendReadBuffer( int index, char *data, int len );
  608. static int appendWriteBuffer( int index , char *data, int len );
  609. static int appendMemBufList( int top, char *data, int len );
  610. static int consumeMemBufList( int top, char *out, int len, int flag, int copyflag );
  611. static int getLineReadBuffer( int index, char *buf, int len );
  612. int tcpstruct_init( char *addr , int p , int timeout_ms , int mem_use , int db )
  613. {
  614.     mbsize = mem_use / sizeof( struct membuf );
  615.     mbuse =0;
  616.     mb_finder = 0;
  617.     mb = ( struct membuf * ) calloc( 1, mbsize * sizeof(struct membuf ));
  618.     if( mb == NULL ) return TCPSTRUCT_ENOMEM;
  619.     bzero( mb , mbsize * sizeof( struct membuf ));
  620.     con = ( struct connection *) calloc( 1, MAXCONNECTION * sizeof( struct connection ));
  621.     if( con == NULL ){
  622.         free( mb );
  623.         return TCPSTRUCT_ENOMEM;
  624.     } else {
  625.         int i;
  626.         for(i=0;i<MAXCONNECTION;i++){
  627.             con[i].use = 0;
  628.             con[i].fd = -1;
  629.         }
  630.     }
  631.     select_timeout.tv_sec = timeout_ms / 1000;
  632.     select_timeout.tv_usec = (timeout_ms - ( timeout_ms/1000)*1000)*1000;
  633.     /* socket */
  634.     mainsockfd = socket( AF_INET , SOCK_STREAM ,  0 );
  635.     if( mainsockfd < 0 ) return TCPSTRUCT_ESOCK;
  636.     
  637.     /* bind */
  638.     bzero( &localaddr ,sizeof( localaddr ));
  639.     localaddr.sin_family = AF_INET;
  640.     localaddr.sin_port = htons( p );
  641.     
  642.     if( addr ){
  643.         localaddr.sin_addr.s_addr = inet_addr( addr );
  644.     } else {
  645.         localaddr.sin_addr.s_addr = htonl( INADDR_ANY );
  646.     }
  647.     if( bind( mainsockfd , (struct sockaddr*) &localaddr ,
  648.               sizeof( localaddr )) < 0 ) return TCPSTRUCT_EBIND;
  649.     /* listen */
  650.     if( listen( mainsockfd , BACKLOGNUM )<0) return TCPSTRUCT_ELISTEN;
  651.     return OK;
  652. }
  653. int tcpstruct_accept1( void )
  654. {
  655.     int tis[BACKLOGNUM];
  656.     int ret;
  657.     ret = tcpstruct_accept( tis , 1 );
  658.     if( ret < 0 ){
  659.         return ret;
  660.     } else if( ret == 1 ){
  661.         return tis[0];
  662.     } else {
  663.         return TCPSTRUCT_EBUG ;
  664.     }
  665. }
  666. int tcpstruct_accept( int *tis , int ticount )
  667. {
  668.     int i;
  669.     int sret;
  670.     int accepted = 0;
  671.     struct timeval t;
  672.     fd_set rfds, wfds , efds;  
  673.     FD_ZERO( & rfds );
  674.     FD_ZERO( & wfds );
  675.     FD_ZERO( & efds );    
  676.     for(i=0;i<MAXCONNECTION;i++){
  677.         if( con[i].use &&
  678.             con[i].fd >= 0 && con[i].closed_by_remote ==0 ){
  679.             FD_SET( con[i].fd , & rfds );
  680.             FD_SET( con[i].fd , & wfds );
  681.             FD_SET( con[i].fd , & efds );
  682.         }
  683.     }
  684.     
  685.     t = select_timeout;
  686.     sret = select( 1024, & rfds , (fd_set*)NULL, & efds , &t);
  687. if( sret > 0 ) {
  688. for(i=0;i< MAXCONNECTION;i++){
  689. if( ( con[i].fd >= 0 ) && FD_ISSET( con[i].fd , &rfds ) ){
  690. int fr = getFreeMem( );
  691. int rr , readsize ;
  692. if( fr <= 0 ) continue;
  693. if( fr > sizeof(tmpbuf ) ){
  694. readsize = sizeof( tmpbuf);
  695. } else {
  696. readsize = fr;
  697. }
  698. rr = read( con[i].fd , tmpbuf , readsize );
  699. if( rr <= 0 ){
  700. con[i].closed_by_remote = 1;
  701. } else {
  702. appendReadBuffer( i , tmpbuf , rr );
  703. }
  704. }
  705. }
  706.     }    
  707.     /* write */
  708.     t = select_timeout;    
  709.     sret = select( 1024, (fd_set*)NULL, &wfds, & efds , &t);
  710. if( sret > 0 ) {
  711. for(i=0;i<MAXCONNECTION;i++){
  712. if( ( con[i].fd >= 0 ) && FD_ISSET( con[i].fd , &wfds )){
  713. char send_buf[4096];
  714. int l , rr;
  715. memset( send_buf, 0, sizeof( send_buf));
  716. l = consumeMemBufList( con[i].mbtop_wi ,send_buf, sizeof(send_buf),0 , 1 );
  717. rr = write( con[i].fd , send_buf , l );
  718. if( rr < 0 ){
  719. con[i].closed_by_remote = 1;
  720. } else {
  721. consumeMemBufList( con[i].mbtop_wi , send_buf, l, 1 , 0 );
  722. }
  723. }
  724. }
  725. }
  726.     for( i=0; i<ticount; i++){
  727.         int asret;
  728.         struct timeval t;
  729.         t.tv_sec =0;
  730.         t.tv_usec =0;
  731.         FD_ZERO( & rfds );
  732.         FD_ZERO( & wfds );
  733.         FD_ZERO( & efds );
  734.         FD_SET( mainsockfd , & rfds );
  735.         FD_SET( mainsockfd , & wfds );
  736.         FD_SET( mainsockfd , & efds );
  737.         asret = select( 1024, &rfds , &wfds , &efds, &t );
  738. // Nuke 20040610: add asret>0 to avoid signal interrupt in select
  739.         if( (asret>0) && FD_ISSET( mainsockfd , & rfds )){
  740.             struct sockaddr_in c;
  741.             int len , newsockfd;
  742.             int newcon;
  743.             bzero( &c , sizeof( c ));
  744.             len = sizeof( c );
  745.             fprintf( stderr, "i can accept " );
  746.             newcon = findregBlankCon( );
  747.             if( newcon < 0 ) continue;
  748.             newsockfd = accept( mainsockfd, (struct sockaddr*)&c , &len );
  749.         log( "同意: %dn" , newsockfd );
  750.             if( newsockfd < 0 ){
  751.                 unregMemBuf( newcon );
  752.                 continue;
  753.             }
  754.             set_nodelay( newsockfd );
  755.             con[newcon].fd = newsockfd;
  756.             memcpy( &con[newcon].remoteaddr , &c ,sizeof(c));
  757.             tis[accepted] = newcon;
  758.             accepted ++;
  759.         }
  760.     }
  761.     return accepted;
  762. }
  763. int tcpstruct_close( int ti )
  764. {
  765.     if( ti < 0 || ti >= MAXCONNECTION )return TCPSTRUCT_EINVCIND;
  766.     if( con[ti].use == 0 ){
  767.         return TCPSTRUCT_ECLOSEAGAIN;
  768.     }
  769.     close( con[ti].fd );
  770.     con[ti].use = 0;
  771.     con[ti].fd = -1;
  772.     /* 伉旦玄毛凶升匀化蝈  毛弁伉失允月 */
  773.     consumeMemBufList( con[ti].mbtop_ri , NULL,
  774.                    mbsize * sizeof( mb[0].buf ), 1, 0 );
  775.     consumeMemBufList( con[ti].mbtop_wi , NULL,
  776.                    mbsize * sizeof( mb[0].buf ), 1, 0 );
  777.     unregMemBuf( con[ti].mbtop_ri );
  778.     unregMemBuf( con[ti].mbtop_wi );
  779.     con[ti].mbtop_ri = -1;
  780.     con[ti].mbtop_wi = -1;    
  781.     return OK;
  782. }
  783. /*
  784.     心仇戈手及互手丹卅仁化}仄井手 remoteclose 分匀凶日 -1 毛井尹允
  785.   
  786.  */
  787. int tcpstruct_read( int ti , char *buf , int len )
  788. {
  789.     int l;
  790.     if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 )
  791.         return TCPSTRUCT_EINVCIND;
  792.     l = consumeMemBufList( con[ti].mbtop_ri , buf , len , 1 , 1);
  793.     if( l == 0  && con[ti].closed_by_remote ) return TCPSTRUCT_EREADFIN;
  794.     return l;
  795. }
  796. /*
  797.   1垫毛方心仇戈[
  798.   int kend : 1卅日垫  及 n 毛诮允
  799.   int kend_r : 1卅日垫  及 r 手诮允(丐木壬)
  800.     心仇戈手及互手丹卅仁化}井勾 remote closed 分匀凶日-1毛井尹允
  801.   // Nuke
  802. Read 1 line
  803. if kend==1 then delete n at the tail
  804. if kend_r== 1 then delete r at the tail (if any)
  805. if no data read, it means 'remote closed' then return -1
  806.  */
  807. int tcpstruct_readline( int ti , char *buf , int len , int kend , int kend_r )
  808. {
  809.     int l;
  810.     int minus = 0;
  811.     if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 )
  812.         return TCPSTRUCT_EINVCIND;
  813.     l = getLineReadBuffer( ti , buf , len );
  814.     if( l == 0 ){
  815.         if( con[ti].closed_by_remote ){
  816.             return TCPSTRUCT_EREADFIN;
  817.         } else {
  818.             return 0;
  819.         }
  820.     }
  821.     
  822.     if( kend ){
  823.         if( buf[l-1]=='n' ){
  824.             buf[l-1] = 0; minus =-1;
  825.         }
  826.     }
  827.     if( kend_r ){
  828.         if( buf[l-1]=='r' ){
  829.             buf[l-1] = 0; minus = -1;
  830.         }
  831.         if( buf[l-2]=='r' ){
  832.             buf[l-2] = 0; minus = -2;
  833.         }
  834.     }
  835.     return l + minus;
  836. }
  837. int tcpstruct_readline_chop( int ti , char *buf, int len )
  838. {
  839.     return tcpstruct_readline( ti , buf , len , 1,1);
  840. }
  841. int tcpstruct_write( int ti , char *buf , int len )
  842. {
  843.     if( ti < 0 || ti >= MAXCONNECTION || con[ti].use == 0 )
  844.         return TCPSTRUCT_EINVCIND;    
  845.     return appendWriteBuffer( ti , buf , len );
  846. }
  847. int tcpstruct_connect( char *addr , int port )
  848. {
  849.     int newti ;
  850.     int s, r;
  851.     struct sockaddr_in svaddr;
  852.     struct hostent *he;
  853.     
  854.     s = socket( AF_INET, SOCK_STREAM , 0 );
  855.     if(s<0)return -2;
  856.     bzero( &svaddr , sizeof( svaddr ));
  857.     svaddr.sin_family = AF_INET;
  858.     svaddr.sin_port = htons( port );
  859.     if( inet_aton( addr, &svaddr.sin_addr ) == 0 ){
  860.         he = gethostbyname( addr );
  861.         if( he == NULL ){
  862.             return TCPSTRUCT_EHOST;
  863.         }
  864.         memcpy( & svaddr.sin_addr.s_addr , he->h_addr ,
  865.                 sizeof( struct in_addr));
  866.     }
  867.     r = connect( s , ( struct sockaddr*)&svaddr,sizeof(svaddr));
  868.     if( r < 0 ){
  869.         return TCPSTRUCT_ECONNECT;
  870.     }
  871.     set_nodelay( s );
  872.     newti = findregBlankCon( );
  873.     if( newti < 0 ){
  874.         fprintf( stderr , "连接失败: newti:%dn", newti );
  875.         return TCPSTRUCT_ECFULL;
  876.     }
  877.     con[newti].fd = s;
  878.     memcpy( & con[newti].remoteaddr , &svaddr ,
  879.             sizeof( struct sockaddr_in));
  880.     return newti;
  881. }
  882. static int appendReadBuffer(  int index , char *data , int len )
  883. {
  884.     int top;
  885.     top = con[index].mbtop_ri;
  886.     for(;;){
  887.         int nextind = mb[top].next;
  888.         if( nextind == -1 ) break;
  889.         top = nextind;
  890.     }
  891.     return appendMemBufList( top , data , len );
  892. }
  893. static int appendWriteBuffer( int index , char *data , int len )
  894. {
  895.     int top;
  896.     top = con[index].mbtop_wi;
  897.     for(;;){
  898.         int nextind = mb[top].next;
  899.         if( nextind == -1 ) break;
  900.         top = nextind;
  901.     }
  902.     return appendMemBufList( top , data , len );
  903. }
  904. static int appendMemBufList( int top , char *data , int len )
  905. {
  906.     int fr = getFreeMem( );
  907.     int rest = len;
  908.     int data_topaddr = 0;
  909.     
  910.     if( len >= fr ){
  911. FILE *fp;
  912. if( (fp=fopen( "badsysinfo.txt", "a+")) != NULL ){
  913. fprintf( fp, "appendMemBufList() len:%d / fr:%d err !! n", len, fr);
  914. fclose( fp);
  915. }
  916. //andy_log
  917. log( "appendMemBufList() len:%d / fr:%d err !! n", len, fr);
  918.         return -1;
  919.     }
  920. data[len] = 0;
  921.     for(;;){
  922.         int blanksize = sizeof( mb[0].buf ) - mb[top].len;
  923.         int cpsize = ( rest <= blanksize ) ? rest : blanksize;
  924.         memcpy( mb[top].buf + mb[top].len ,
  925.                 data + data_topaddr , cpsize );
  926.         mb[top].len += cpsize;
  927.         if( rest <= blanksize ){
  928.             return len;
  929.         } else {
  930.             int newmb;
  931.             rest -= cpsize;
  932.             data_topaddr += cpsize;
  933.             if( (newmb = findregBlankMemBuf( ) ) == TCPSTRUCT_EMBFULL ){
  934. FILE *fp;
  935. if( (fp=fopen( "badsysinfo.txt", "a+")) != NULL ){
  936. fprintf( fp, "find newmb == TCPSTRUCT_EMBFULL err data:%s !!n", data);
  937. fclose( fp);
  938. }
  939. log( "find newmb == TCPSTRUCT_EMBFULL err data:%s !!n", data);
  940. }
  941.             mb[top].next = newmb;
  942.             top = mb[top].next;
  943.         }
  944.     }
  945.     return TCPSTRUCT_EBUG;
  946. }
  947. static int consumeMemBufList( int top , char *out , int len ,
  948.                           int consumeflag , int copyflag )
  949. {
  950.     int total = 0;
  951.     int top_store = top;
  952.     for(;;){
  953.         int cpsize;
  954.         if( top == -1 ) break;
  955.         cpsize = ( mb[top].len <= ( len - total) ) ?
  956.             mb[top].len : ( len - total );
  957.         if( copyflag ) memcpy( out + total , mb[top].buf , cpsize );
  958.         total += cpsize;
  959.         if( consumeflag ){
  960.             mb[top].len -= cpsize;
  961.             if( mb[top].len > 0 ){
  962.                 /* 勾井中反凶仄化卅中及匹memmove */
  963.                 memmove( mb[top].buf , mb[top].buf + cpsize ,
  964.                          sizeof( mb[top].buf ) - cpsize );
  965.             }
  966.         }
  967.         top = mb[top].next;
  968.         if( total == len ){
  969.             break;
  970.         }
  971.     }
  972.     if( consumeflag ){
  973.         /* 卅互今互0卞卅匀化月卅日荸  [匹手  赓及支勾反荸  仄卅中冗 */
  974.         top = mb[top_store].next;
  975.         for(;;){
  976.             if( top == -1 )break;
  977.             if( mb[top].len == 0 ){
  978.                 int prev;
  979.                 mb[top_store].next = mb[top].next;
  980.                 prev = top;
  981.                 top = mb[top].next;
  982.                 unregMemBuf( prev );
  983.             } else {
  984.                 top = mb[top].next;
  985.             }
  986.         }
  987.     }
  988.     
  989.     return total;
  990. }
  991. static int getLineReadBuffer( int index , char *buf, int len )
  992. {
  993.     int top = con[index].mbtop_ri;
  994.     int ti = 0 , breakflag = 0;
  995.     for(;;){
  996.         int i;        
  997.         int l = mb[top].len;
  998.         if( top == -1 )break;
  999.         for( i=0 ; i < l ; i++){
  1000.             if( mb[top].buf[i] == 'n' ){
  1001.                 breakflag = 1;
  1002.                 break;
  1003.             }
  1004.             ti ++;
  1005.         }
  1006.         if( breakflag )break;
  1007.         top = mb[top].next;
  1008.     }
  1009.     if( ti > len ){
  1010.         /* 1垫互卅互允亢月[    卅巨仿□毛井尹六 */
  1011.         return TCPSTRUCT_ETOOLONG;
  1012.     }
  1013.     /* 垫互敦岳仄化卅中 */
  1014.     if( breakflag == 0 ){
  1015.         return 0;
  1016.     }
  1017.     return consumeMemBufList( con[index].mbtop_ri , buf , ti+1 , 1 , 1 );
  1018. }
  1019. /*
  1020.     心仇户月    赢今毛忒允
  1021.   int index : con index
  1022.   return:
  1023.     反巨仿□
  1024.   0动晓及桦宁反 read 仄化手方中赢今[
  1025.   mbsize 井日mbuse 毛娄中化扔奶术毛井仃月分仃[
  1026.   仇引井中芴曰及坌反  骰允月[公氏卅称井中袄卞仇分歹日卅仁化手第[
  1027.   
  1028.  */   
  1029. static int getFreeMem( void )
  1030. {
  1031.     return ( mbsize - mbuse ) * sizeof( mb[0].buf );
  1032. }
  1033. /*
  1034.   
  1035.   membuf 及坞五毛茧仄分允[
  1036.   return : 心勾井匀凶日 >=0 匹 index.
  1037.   心勾井日卅井匀凶日  
  1038.   腹绸及午五卞反 mb_finder 毛勾井丹[
  1039.   仇木匹腹绸仄化}    卞reg允月[
  1040.  */
  1041. static int findregBlankMemBuf( void  )
  1042. {
  1043.     int i;
  1044.     for(i=0;i<mbsize;i++){
  1045.         mb_finder ++;
  1046.         if( mb_finder >= mbsize || mb_finder < 0 ) mb_finder = 0;
  1047.         if( mb[mb_finder].use == 0 ){
  1048.             mb[mb_finder].use = 1;
  1049.             mb[mb_finder].len = 0;
  1050.             mb[mb_finder].next = -1;
  1051.             mbuse ++;
  1052.             return mb_finder;
  1053.         }
  1054.     }
  1055.     return TCPSTRUCT_EMBFULL;
  1056. }
  1057. /*
  1058.   mb 毛荸  允月
  1059.   
  1060.  */
  1061. static int unregMemBuf(  int index )
  1062. {
  1063.     mb[index].use=0;
  1064.     mb[index].next = -1;
  1065.     mb[index].len = 0;
  1066.     mbuse --;
  1067.     return OK;
  1068. }
  1069. static int findregBlankCon( void )
  1070. {
  1071.     int i;
  1072. // Nuke changed 0->1
  1073. //for(i=0;i<MAXCONNECTION;i++){
  1074.     for(i=1;i<MAXCONNECTION;i++){
  1075.         if( con[i].use == 0 ){
  1076.             con[i].use = 1;
  1077.             con[i].fd = -1;
  1078.             con[i].mbtop_ri = findregBlankMemBuf();
  1079.             if( con[i].mbtop_ri < 0 ){
  1080.                 fprintf( stderr , "EMBFULLn" );
  1081.                 return TCPSTRUCT_EMBFULL;
  1082.             }
  1083.             
  1084.             con[i].mbtop_wi = findregBlankMemBuf();
  1085.             if( con[i].mbtop_wi < 0 ){
  1086.                 unregMemBuf( con[i].mbtop_ri );
  1087.                 fprintf( stderr , "EMBFULLn" );
  1088.                 return TCPSTRUCT_EMBFULL;
  1089.             }
  1090.             bzero( & con[i].remoteaddr , sizeof( struct sockaddr_in));
  1091.             con[i].closed_by_remote = 0;
  1092.             return i;
  1093.         }
  1094.     }
  1095.     return TCPSTRUCT_ECFULL;
  1096. }
  1097. int tcpstruct_countmbuse( void )
  1098. {
  1099.     int i,c=0;
  1100.     for(i=0;i<mbsize;i++){
  1101.         if( mb[i].use )c++;
  1102.     }
  1103.     return c;
  1104. }
  1105. char * getGSName( int i )
  1106. {
  1107.     return gs[i].name;
  1108. }
  1109. void checkGSUCheck( char *id )
  1110. {
  1111.     int i;
  1112.     char gname[256];
  1113.     if(!id[0]) return;
  1114. memset( gname, 0,  sizeof( gname) );
  1115. if( LockNode_getGname( (getHash(id) & 0xff), id, gname) <= 0 ){
  1116. log("无法从游戏中找到账号:%x/%s !!n", getHash( id), id);
  1117. return;
  1118. }
  1119. log("n");
  1120.     for(i=0; i < MAXCONNECTION; i++ ){
  1121.         if( gs[i].name[0] && strcmp( gs[i].name , gname )==0){
  1122.           log("发送解锁检查[%s] 到 %d.%x/%s 服务器:%d !!n", id, i, getHash( id), gname, gs[i].fd);
  1123. saacproto_ACUCheck_send( gs[i].fd , id );
  1124. return;
  1125.         }
  1126.     }
  1127. // log("Can't find gname:%s sending err !!n", gname);
  1128. int ret = -1;
  1129. if( !isLocked( id) ) {
  1130. log( "删除内存信息: 用户:%x/%s 没有锁定!!n", getHash(id), id);
  1131. }
  1132. if( DeleteMemLock( getHash(id) & 0xff, id, &ret) ) {
  1133. } else {
  1134. log( "不能解锁 %x:%s !n", getHash(id), id);
  1135. }
  1136. }
  1137. void set_nodelay( int sock )
  1138. {
  1139.     int flag = 1;
  1140.     int result = setsockopt( sock, IPPROTO_TCP, TCP_NODELAY,
  1141.                              (char*)&flag, sizeof(int));
  1142.     if( result < 0 ){
  1143.         log( "不能设置延迟.n" );
  1144.     } else {
  1145.         log( "设置延迟: fd:%dn", sock );
  1146.     }
  1147. }
  1148. /*
  1149.   允屯化及必□丞扔□田□卞  霜[
  1150.   int flag : 1分匀凶日霜耨葭卞反云仁日卅中
  1151.   
  1152.  */
  1153. void gmsvBroadcast( int fd, char *p1, char *p2, char *p3 , int flag )
  1154. {
  1155.     int i,c=0;
  1156.     
  1157.     for(i=0;i<MAXCONNECTION;i++){
  1158.         if( ( flag == 1 ) && ( i == fd ) )continue;
  1159.         if( gs[i].use && gs[i].name[0] ){
  1160.             saacproto_Broadcast_send( i, p1,p2,p3);
  1161.             c++;
  1162.         }
  1163.     }
  1164. /*
  1165. #if 1
  1166.     {
  1167.         char fn[1000];
  1168.         FILE *fp;
  1169.         snprintf( fn, sizeof(fn), "%s/broadcast.log" , logdir );
  1170.         fp = fopen( fn,"a" );
  1171.         if(fp){
  1172.             fprintf( fp, "From %s(%d) Id:[%s] Char:[%s] Mesg:[%s]n",
  1173.                      gs[fd].name, fd, p1,p2,p3 );
  1174.             fclose(fp);
  1175.         }
  1176.     }
  1177. #endif
  1178. */
  1179. }
  1180. #ifdef _ANGEL_SUMMON
  1181. #define MISSIONFILE "db/missiontable.txt"
  1182. static int initMissionTable( void )
  1183. {
  1184. FILE *fp;
  1185. char onedata[1024];
  1186. char buf[1024];
  1187. int index =0;
  1188. memset( missiontable, 0, sizeof(missiontable));
  1189. fp = fopen( MISSIONFILE, "r");
  1190. if( !fp ) {
  1191. log("n加载精灵召唤错误!!!! n");
  1192. //return false;
  1193. }
  1194. log("n加载精灵召唤...");
  1195. while(1) {
  1196. //
  1197. if( fgets( onedata, sizeof(onedata), fp) == NULL)
  1198. break;
  1199. if( onedata[0] == '' || onedata[0] == '#' )
  1200. continue;
  1201. //easyGetTokenFromBuf( onedata, ",", 1, buf, sizeof( buf));
  1202. //index = atoi( buf);
  1203. easyGetTokenFromBuf( onedata, ",", 1, buf, sizeof( buf));
  1204. if( buf[0] == '' ) continue;
  1205. strcpy( missiontable[index].angelinfo, buf);
  1206. easyGetTokenFromBuf( onedata, ",", 2, buf, sizeof( buf));
  1207. if( buf[0] == '' ) continue;
  1208. strcpy( missiontable[index].heroinfo, buf);
  1209. easyGetTokenFromBuf( onedata, ",", 3, buf, sizeof( buf));
  1210. if( buf[0] == '' ) continue;
  1211. missiontable[index].mission = atoi( buf);
  1212. easyGetTokenFromBuf( onedata, ",", 4, buf, sizeof( buf));
  1213. if( buf[0] == '' ) continue;
  1214. missiontable[index].flag = atoi( buf);
  1215. easyGetTokenFromBuf( onedata, ",", 5, buf, sizeof( buf));
  1216. if( buf[0] == '' ) continue;
  1217. missiontable[index].time = atoi( buf);
  1218. easyGetTokenFromBuf( onedata, ",", 6, buf, sizeof( buf));
  1219. if( buf[0] == '' ) continue;
  1220. missiontable[index].limittime = atoi( buf);
  1221. log("%d=%s,%s,%d,%d,%d,%d n", index,
  1222. missiontable[index].angelinfo,
  1223. missiontable[index].heroinfo,
  1224. missiontable[index].mission,
  1225. missiontable[index].flag,
  1226. missiontable[index].time,
  1227. missiontable[index].limittime );
  1228. index++;
  1229. if( index >= MAXMISSIONTABLE) break;
  1230. }
  1231. fclose( fp);
  1232. log("..成功! n");
  1233. //return true;
  1234. }
  1235. int saveMissionTable( void )
  1236. {
  1237. FILE *fp;
  1238. char onedata[1024];
  1239. char buf[1024];
  1240. int index =0;
  1241. fp = fopen( MISSIONFILE, "w");
  1242. if( !fp ) {
  1243. log("n打开精灵召唤错误!!!! n");
  1244. //return false;
  1245. }
  1246. log("n保存精灵召唤...");
  1247. for( index =0; index < MAXMISSIONTABLE; index++) {
  1248. if( missiontable[index].angelinfo[0] == '' )
  1249. continue;
  1250. sprintf( onedata, "%s,%s,%d,%d,%d,%dn",
  1251. missiontable[index].angelinfo,
  1252. missiontable[index].heroinfo,
  1253. missiontable[index].mission,
  1254. missiontable[index].flag,
  1255. missiontable[index].time,
  1256. missiontable[index].limittime );
  1257. fputs( onedata, fp);
  1258. }
  1259. fclose( fp);
  1260. log("..成功! n");
  1261. //return true;
  1262. }
  1263. void delMissionTableOnedata( int index)
  1264. {
  1265. int gi;
  1266. log("n删除精灵召唤:%d:%s:%s n", index, missiontable[index].angelinfo, missiontable[index].heroinfo);
  1267. if( index <0 || index >=MAXMISSIONTABLE) return;
  1268. strcpy( missiontable[index].angelinfo, "");
  1269. strcpy( missiontable[index].heroinfo, "");
  1270. missiontable[index].mission = 0;
  1271. missiontable[index].flag = MISSION_NONE;
  1272. missiontable[index].time = 0;
  1273. missiontable[index].limittime = 0;
  1274. for( gi=0; gi<MAXCONNECTION; gi++) {
  1275. if (gs[gi].use && gs[gi].name[0]) {
  1276. saacproto_ACMissionTable_send( gi, index, 3, "", "");
  1277. }
  1278. }
  1279. }
  1280. #define ANSWERTIME 1 // 等待回答时间(小时)
  1281. //#define DOINGTIME 3*24 // 任务时间(小时)
  1282. #define BOUNDSTIME 1*24 // 保留时间(小时)
  1283. void checkMissionTimelimit( void)
  1284. {
  1285. int index;
  1286. static time_t lastcheck =0;
  1287. if( sys_time < lastcheck + 5*60 )
  1288. return;
  1289. log("n检查精灵召唤时间限制:%d n", sys_time);
  1290. for( index =0; index < MAXMISSIONTABLE; index++) {
  1291. if( missiontable[index].flag == MISSION_NONE) {
  1292. continue;
  1293. }
  1294. // 等待使者回应1小时
  1295. else if( missiontable[index].flag == MISSION_WAIT_ANSWER
  1296. && sys_time > missiontable[index].time + ANSWERTIME*60*60 ) {
  1297. delMissionTableOnedata( index);// 删
  1298. }
  1299. // 等待领奖完成 limittime小时
  1300. else if( ( missiontable[index].flag == MISSION_DOING || missiontable[index].flag == MISSION_HERO_COMPLETE )
  1301. && ( sys_time > (missiontable[index].time + missiontable[index].limittime*60*60))  ) {
  1302. char buf[1024];
  1303. int gi;
  1304. // 改TIMEOVER
  1305. log("精灵召唤及领奖时间过:%d ", index);
  1306. missiontable[index].flag = MISSION_TIMEOVER;
  1307. missiontable[index].time = time(NULL);
  1308. missiontable[index].limittime = BOUNDSTIME;
  1309. sprintf( buf, "%d|%s|%s|%d|%d|%d|%d ", index,
  1310. missiontable[index].angelinfo,
  1311. missiontable[index].heroinfo,
  1312. missiontable[index].mission,
  1313. missiontable[index].flag,
  1314. missiontable[index].time,
  1315. missiontable[index].limittime );
  1316. for( gi=0; gi<MAXCONNECTION; gi++) {
  1317. if (gs[gi].use && gs[gi].name[0]) {
  1318. saacproto_ACMissionTable_send( gi, 1, 1, buf, "");
  1319. }
  1320. }
  1321. continue;
  1322. }
  1323. //else if( missiontable[index].flag == MISSION_HERO_COMPLETE
  1324. // && sys_time > missiontable[index].time + BOUNDSTIME*60*60 ) {
  1325. // log(" 领奖时间过:%d ", index);
  1326. // delMissionTableOnedata( index);// 删
  1327. //}
  1328. // 资料保留时间(BOUNDSTIME小时)
  1329. else if( missiontable[index].flag == MISSION_TIMEOVER
  1330. && sys_time > missiontable[index].time + BOUNDSTIME*60*60 ) {
  1331. log(" 保留时间过:%d ", index);
  1332. delMissionTableOnedata( index);// 删
  1333. }
  1334. }
  1335. saveMissionTable();
  1336. lastcheck = sys_time;
  1337. }
  1338. #endif