⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 d_net.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 3 页
字号:
                           if( cmpack(node->acktosend[i],nextfirstack)<=0 )                           {                               if( node->acktosend[i]==nextfirstack )                               {                                   node->firstacktosend=nextfirstack++;                                   if(nextfirstack==0) nextfirstack=1;                                   change=true;                               }                               if( i==node->acktosend_tail )                               {                                   node->acktosend[node->acktosend_tail] = 0;                                   node->acktosend_tail = (i+1)%MAXACKTOSEND;                               }                               else                                   if( i==hm1 )                                   {                                       node->acktosend[hm1] = 0;                                       node->acktosend_head = hm1;                                       hm1=(hm1-1+MAXACKTOSEND)%MAXACKTOSEND;                                    }                                                              }                   }               }               else               { // out of order packet                 // don't increment firsacktosend, put it in asktosend queue                   // will be incremented when the nextfirstack come (code above)                   byte newhead=(node->acktosend_head+1)%MAXACKTOSEND;                   DEBFILE(va("out of order packet (%d expected)\n",nextfirstack));                   if(newhead != node->acktosend_tail)                   {                       node->acktosend[node->acktosend_head]=ack;                       node->acktosend_head = newhead;                   }                   else // buffer full discard packet, sender will resend it                       // remark that we can admit the packet but we will not detect the duplication after :(                   {                       DEBFILE("no more freeackret\n");                       goodpacket=false;                   }               }           }       }   }   return goodpacket;}// send special packet with only ack on itextern void Net_SendAcks(int node){    netbuffer->packettype = PT_NOTHING;    memcpy(netbuffer->u.textcmd,nodes[node].acktosend,MAXACKTOSEND);    HSendPacket(node,false,0,MAXACKTOSEND);}static void GotAcks(void){    int i,j;    for(j=0;j<MAXACKTOSEND;j++)        if( netbuffer->u.textcmd[j] )           for(i=0;i<MAXACKPACKETS;i++)               if( ackpak[i].acknum &&                    ackpak[i].destinationnode==doomcom->remotenode)               {                   if( ackpak[i].acknum==netbuffer->u.textcmd[j])                       Removeack(i);                   else                   // nextacknum is first equal to acknum, then when receiving bigger ack                   // there is big chance the packet is lost                   // when resent, nextacknum=nodes[node].nextacknum this will redo the same but with differant value                   if( cmpack(ackpak[i].nextacknum,netbuffer->u.textcmd[j])<=0 && ackpak[i].senttime>0)                       ackpak[i].senttime--; // hurry up               }}void Net_ConnectionTimeout( int node ){    // send a very special packet to self (hack the reboundstore queu)    // main code will handle it    reboundstore[rebound_head].packettype = PT_NODETIMEOUT;    reboundstore[rebound_head].ack = 0;    reboundstore[rebound_head].ackreturn = 0;    reboundstore[rebound_head].u.textcmd[0] = node;    reboundsize[rebound_head]=BASEPACKETSIZE+1;    rebound_head=(rebound_head+1)%MAXREBOUND;    // do not redo it quickly (if we do not close connection is for a good reason !)    nodes[node].lasttimepacketreceived = I_GetTime();}// resend the data if neededextern void Net_AckTicker(void){    int i;    for(i=0;i<MAXACKPACKETS;i++)    {        node_t *node=&nodes[ackpak[i].destinationnode];        if(ackpak[i].acknum)            if(ackpak[i].senttime+node->timeout<I_GetTime())            {                if( ackpak[i].resentnum > 10 && (node->flags & CLOSE) )                {                    DEBFILE(va("ack %d sent 20 time so connection is supposed lost : node %d\n",i,node-nodes));                    Net_CloseConnection( (node-nodes) | FORCECLOSE);                    ackpak[i].acknum = 0;                    continue;                }                DEBFILE(va("Resend ack %d, %d<%d\n",ackpak[i].acknum,                           ackpak[i].senttime,                           node->timeout,                           I_GetTime()));                memcpy(netbuffer,ackpak[i].pak,ackpak[i].length);                ackpak[i].senttime=I_GetTime();                ackpak[i].resentnum++;                ackpak[i].nextacknum=node->nextacknum;                retransmit++; // for stat                HSendPacket(node-nodes,false,ackpak[i].acknum,ackpak[i].length-BASEPACKETSIZE);            }    }    for(i=1;i<MAXNETNODES;i++)    {        // this is something like node open flag        if( nodes[i].firstacktosend )        {            // we haven't sent a packet since long time acknoledge packet if needed            if( nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime() )                Net_SendAcks(i);            if( (nodes[i].flags & CLOSE) == 0 &&                 nodes[i].lasttimepacketreceived + CONNECTIONTIMEOUT < I_GetTime() )                Net_ConnectionTimeout( i );        }    }}// remove last packet received ack before the resend the ackret// (the higer layer don't have room, or something else ....)extern void Net_UnAcknowledgPacket(int node){    int hm1=(nodes[node].acktosend_head-1+MAXACKTOSEND)%MAXACKTOSEND;    DEBFILE(va("UnAcknowledg node %d\n",node));    if(!node)        return;    if( nodes[node].acktosend[hm1] == netbuffer->ack )    {        nodes[node].acktosend[hm1] = 0;        nodes[node].acktosend_head = hm1;    }    else    if( nodes[node].firstacktosend == netbuffer->ack )    {        nodes[node].firstacktosend--;        if( nodes[node].firstacktosend==0 )            nodes[node].firstacktosend--;    }    else    {        while (nodes[node].firstacktosend!=netbuffer->ack)        {            nodes[node].acktosend_tail = (nodes[node].acktosend_tail-1+MAXACKTOSEND)%MAXACKTOSEND;            nodes[node].acktosend[nodes[node].acktosend_tail]=nodes[node].firstacktosend;            nodes[node].firstacktosend--;            if( nodes[node].firstacktosend==0 ) nodes[node].firstacktosend--;        }        nodes[node].firstacktosend++;        if( nodes[node].firstacktosend==0 ) nodes[node].firstacktosend++;    }//    I_Error("can't Removing ackret\n");}extern boolean Net_AllAckReceived(void){   int i;   for(i=0;i<MAXACKPACKETS;i++)      if(ackpak[i].acknum)          return false;   return true;}// wait the all ackreturn with timout in secondextern void Net_WaitAllAckReceived( ULONG timeout ){    tic_t tictac=I_GetTime();    timeout=tictac+timeout*TICRATE;    HGetPacket();    while(timeout>I_GetTime() && !Net_AllAckReceived())    {        while(tictac==I_GetTime()) ;        tictac=I_GetTime();        HGetPacket();        Net_AckTicker();    }}static void InitNode( int node ){    nodes[node].acktosend_head  = 0;    nodes[node].acktosend_tail  = 0;    nodes[node].ping            = PINGDEFAULT;    nodes[node].varping         = VARPINGDEFAULT;    nodes[node].timeout         = TIMEOUT(nodes[node].ping,nodes[node].varping);    nodes[node].firstacktosend  = 0;    nodes[node].nextacknum      = 1;    nodes[node].remotefirstack  = 0;    nodes[node].flags           = 0;}static void InitAck(){   int i;   for(i=0;i<MAXACKPACKETS;i++)      ackpak[i].acknum=0;   for(i=0;i<MAXNETNODES;i++)       InitNode( i );}extern void Net_AbortPacketType(char packettype){    int i;    for( i=0;i<MAXACKPACKETS;i++ )         if( ackpak[i].acknum &&              (((doomdata_t *)ackpak[i].pak)->packettype==packettype || packettype==-1 ))             ackpak[i].acknum=0;}// -----------------------------------------------------------------//  end of acknowledge function// -----------------------------------------------------------------// remove a node, clear all ack from this node and reset askretextern void Net_CloseConnection(int node){    int i;    boolean forceclose = (node & FORCECLOSE)!=0;    node &= ~FORCECLOSE;    if( !node )        return;    nodes[node].flags |= CLOSE;    // try to Send ack back (two army problem)    if( GetAcktosend(node) )    {        Net_SendAcks( node );        Net_SendAcks( node );    }    // check if we wait ack from this node    for(i=0;i<MAXACKPACKETS;i++)        if( ackpak[i].acknum && ackpak[i].destinationnode==node)        {            if( !forceclose )                return;     // connection will be closed when ack is returned            else                ackpak[i].acknum = 0;        }    InitNode(node);    AbortSendFiles(node);    I_NetFreeNodenum(node);}//// Checksum//static unsigned NetbufferChecksum (void){    unsigned    c;    int         i,l;    unsigned char   *buf;    c = 0x1234567;    l = doomcom->datalength - 4;    buf = (unsigned char*)netbuffer+4;    for (i=0 ; i<l ; i++,buf++)        c += (*buf) * (i+1);    return c;}#ifdef DEBUGFILEstatic void fprintfstring(char *s,byte len){    int i;    int mode=0;    for (i=0 ; i<len ; i++)       if(s[i]<32)           if(mode==0) {               fprintf (debugfile,"[%d",(byte)s[i]);               mode = 1;           } else               fprintf (debugfile,",%d",(byte)s[i]);       else       {           if(mode==1) {              fprintf (debugfile,"]");              mode=0;           }           fprintf (debugfile,"%c",s[i]);       }    if(mode==1) fprintf (debugfile,"]");    fprintf(debugfile,"\n");}static char *packettypename[NUMPACKETTYPE]={    "NOTHING",    "SERVERCFG",    "CLIENTCMD",    "CLIENTMIS",    "CLIENT2CMD",    "CLIENT2MIS",    "NODEKEEPALIVE",    "NODEKEEPALIVEMIS",    "SERVERTICS",    "SERVERREFUSE",    "SERVERSHUTDOWN",    "CLIENTQUIT",    "ASKINFO",    "SERVERINFO",    "REQUESTFILE",    "FILEFRAGMENT",    "TEXTCMD",    "TEXTCMD2",    "CLIENTJOIN",    "NODETIMEOUT",};static void DebugPrintpacket(char *header){    fprintf (debugfile,"%-12s (node %d,ack %d,ackret %d,size %d) type(%d) : %s\n"                      ,header                      ,doomcom->remotenode                      ,netbuffer->ack                      ,netbuffer->ackreturn                      ,doomcom->datalength                      ,netbuffer->packettype,packettypename[netbuffer->packettype]);    switch(netbuffer->packettype)    {       case PT_ASKINFO:           fprintf(debugfile                  ,"    time %u\n"                  ,(unsigned int)netbuffer->u.askinfo.time);           break;       case PT_CLIENTJOIN:           fprintf(debugfile                  ,"    number %d mode %d\n"                  ,netbuffer->u.clientcfg.localplayers                  ,netbuffer->u.clientcfg.mode);           break;       case PT_SERVERTICS:           fprintf(debugfile                  ,"    firsttic %d ply %d tics %d ntxtcmd %d\n    "                  ,ExpandTics (netbuffer->u.serverpak.starttic)                  ,netbuffer->u.serverpak.numplayers                  ,netbuffer->u.serverpak.numtics                  ,(int)(&((char *)netbuffer)[doomcom->datalength] - (char *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numplayers*netbuffer->u.serverpak.numtics]));           fprintfstring(                                            (char *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numplayers*netbuffer->u.serverpak.numtics]                        ,&((char *)netbuffer)[doomcom->datalength] - (char *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numplayers*netbuffer->u.serverpak.numtics]);           break;       case PT_CLIENTCMD:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -