Esempio n. 1
0
// resend the data if needed
void Net_AckTicker(void)
{
#ifndef NONET
	INT32 i;

	for (i = 0; i < MAXACKPACKETS; i++)
	{
		const INT32 nodei = ackpak[i].destinationnode;
		node_t *node = &nodes[nodei];
#ifdef NEWPING
		if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
#else
		if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
#endif
		{
			if (ackpak[i].resentnum > 10 && (node->flags & CLOSE))
			{
				DEBFILE(va("ack %d sent 10 times so connection is supposed lost: node %d\n",
					i, nodei));
				Net_CloseConnection(nodei | FORCECLOSE);

				ackpak[i].acknum = 0;
				continue;
			}
#ifdef NEWPING
			DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
				NODETIMEOUT, I_GetTime()));
#else
			DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
				node->timeout, I_GetTime()));
#endif
			M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length);
			ackpak[i].senttime = I_GetTime();
			ackpak[i].resentnum++;
			ackpak[i].nextacknum = node->nextacknum;
			retransmit++; // for stat
			HSendPacket((INT32)(node - nodes), false, ackpak[i].acknum,
				(size_t)(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 for a long time
			// acknowledge packet if needed
			if (nodes[i].lasttimeacktosend_sent + ACKTOSENDTIMEOUT < I_GetTime())
				Net_SendAcks(i);

			if (!(nodes[i].flags & CLOSE)
				&& nodes[i].lasttimepacketreceived + connectiontimeout < I_GetTime())
			{
				Net_ConnectionTimeout(i);
			}
		}
	}
#endif
}
Esempio n. 2
0
// send special packet with only ack on it
void Net_SendAcks(INT32 node)
{
#ifdef NONET
	(void)node;
#else
	netbuffer->packettype = PT_NOTHING;
	M_Memcpy(netbuffer->u.textcmd, nodes[node].acktosend, MAXACKTOSEND);
	HSendPacket(node, false, 0, MAXACKTOSEND);
#endif
}
Esempio n. 3
0
void NetUpdate (void)
{
    int             nowtime;
    int             newtics;
    int				i,j;
    int				realstart;
    int				gameticdiv;
    
    // check time
    nowtime = I_GetTime ()/ticdup;
    newtics = nowtime - gametime;
    gametime = nowtime;
	
    if (newtics <= 0) 	// nothing new to update
	goto listen; 

    if (skiptics <= newtics)
    {
	newtics -= skiptics;
	skiptics = 0;
    }
    else
    {
	skiptics -= newtics;
	newtics = 0;
    }
	
		
    netbuffer->player = consoleplayer;
    
    // build new ticcmds for console player
    gameticdiv = gametic/ticdup;
    for (i=0 ; i<newtics ; i++)
    {
	I_StartTic ();
	D_ProcessEvents ();
	if (maketic - gameticdiv >= BACKUPTICS/2-1)
	    break;          // can't hold any more
	
	//printf ("mk:%i ",maketic);
	G_BuildTiccmd (&localcmds[maketic%BACKUPTICS]);
	maketic++;
    }


    if (singletics)
	return;         // singletic update is syncronous
    
    // send the packet to the other nodes
    for (i=0 ; i<doomcom->numnodes ; i++)
	if (nodeingame[i])
	{
	    netbuffer->starttic = realstart = resendto[i];
	    netbuffer->numtics = maketic - realstart;
	    if (netbuffer->numtics > BACKUPTICS)
		I_Error ("NetUpdate: netbuffer->numtics > BACKUPTICS");

	    resendto[i] = maketic - doomcom->extratics;

	    for (j=0 ; j< netbuffer->numtics ; j++)
		netbuffer->cmds[j] = 
		    localcmds[(realstart+j)%BACKUPTICS];
					
	    if (remoteresend[i])
	    {
		netbuffer->retransmitfrom = nettics[i];
		HSendPacket (i, NCMD_RETRANSMIT);
	    }
	    else
	    {
		netbuffer->retransmitfrom = 0;
		HSendPacket (i, 0);
	    }
	}
    
    // listen for other packets
  listen:
    GetPackets ();
}
Esempio n. 4
0
void D_ArbitrateNetStart (void)
{
	int             i;
	boolean gotinfo[MAXNETNODES];
	boolean gotClass[MAXNETNODES];
#ifdef __WATCOMC__
	int nextTic;
	extern volatile int ticcount;

	nextTic = ticcount+8;
#endif

	autostart = true;

	memset (gotClass,0,sizeof(gotClass));
	memset (gotinfo,0,sizeof(gotinfo));
	gotClass[doomcom->consoleplayer] = true;
	do
	{
		i = 0;

		CheckAbort();
		while(HGetPacket())
		{ // Check for any incoming packets
			if(netbuffer->checksum&NCMD_SETUP && netbuffer->starttic >= 64)
			{
				
				PlayerClass[netbuffer->player] = netbuffer->starttic&0x3f;
				if(!gotClass[netbuffer->player])
				{
					gotClass[netbuffer->player] = true;
					ST_NetProgress();
					ST_Message("\n");
				}
				if(netbuffer->retransmitfrom)
				{ // that node has received info from all other nodes
					gotinfo[netbuffer->player] = true;
				}
			}
		}
#ifdef __WATCOMC__
		if(ticcount <= nextTic)
		{ // only send packets every half second
			continue;
		}
		nextTic = ticcount+8;
#endif
		// Keep sending out packets containing the console class
		for(i = 0; i < doomcom->numnodes; i++)
		{
			netbuffer->player = doomcom->consoleplayer;
			netbuffer->starttic = PlayerClass[doomcom->consoleplayer]+64;
			netbuffer->retransmitfrom = gotinfo[doomcom->consoleplayer];
			netbuffer->numtics = 0;
			HSendPacket(i, NCMD_SETUP);
		}
		for(i = 0; i < doomcom->numnodes; i++)
		{ // Make sure that all nodes have sent class info
			if (!gotClass[i])
			{
				ST_Message(".");
				break;
			}
		}
		if(i < doomcom->numnodes)
		{
			continue;
		}
		else
		{ // consoleplayer has received all player classes
			if(gotinfo[doomcom->consoleplayer])
			{
				CheckAbort();
			}
			else
			{
				gotinfo[doomcom->consoleplayer] = true;
				ST_Message("All player classes received, ready to proceed\n");
				ST_NetDone();
			}
		}
		for (i = 0; i < doomcom->numnodes; i++)
		{ // Make sure that all nodes are ready to proceed
			if (!gotinfo[i])
			{
				break;
			}
		}
	} while(i < doomcom->numnodes);

	memset (gotinfo,0,sizeof(gotinfo));

	if (doomcom->consoleplayer)
	{       // listen for setup info from key player
//              ST_Message ("listening for network start info...\n");
		while (1)
		{
			CheckAbort ();
			if (!HGetPacket ())
				continue;
			if(netbuffer->checksum & NCMD_SETUP && netbuffer->starttic < 64)
			{
				if (netbuffer->player != VERSION)
					I_Error ("Different HEXEN versions cannot play a net game!");
				startskill = netbuffer->retransmitfrom & 15;
				deathmatch = (netbuffer->retransmitfrom & 0xc0) >> 6;
				nomonsters = (netbuffer->retransmitfrom & 0x20) > 0;
				respawnparm = (netbuffer->retransmitfrom & 0x10) > 0;
				startmap = netbuffer->starttic & 0x3f;
				startepisode = 1;
				return;
			}
		}
	}
	else
	{       // key player, send the setup info
//              ST_Message ("sending network start info...\n");
		do
		{