示例#1
0
static void CheckQueuedPackets(void)
{

  int i;
  for (i=0; (unsigned)i<numqueuedpackets; i++)
    if (doom_ntohl(queuedpacket[i]->tic) <= gametic)
      switch (queuedpacket[i]->type) {
      case PKT_QUIT: // Player quit the game
  {
    int pn = *(byte*)(queuedpacket[i]+1);
    playeringame[pn] = false;
    doom_printf("Player %d left the game\n", pn);
  }
  break;
      case PKT_EXTRA:
  {
    int *p = (int*)(queuedpacket[i]+1);
    size_t len = LONG(*(p+2));
    switch (LONG(*p)) {
    case nm_plcolour:
      G_ChangedPlayerColour(LONG(*(p+1)), LONG(*(p+3)));
      break;
    case nm_savegamename:
      if (len < SAVEDESCLEN) {
        memcpy(savedescription, p+3, len);
        // Force terminating 0 in case
        savedescription[len] = 0;
      }
      break;
    }
  }
  break;
      default: // Should not be queued
  break;
      }

  { // Requeue remaining packets
    int newnum = 0;
    packet_header_t **newqueue = NULL;

    for (i=0; (unsigned)i<numqueuedpackets; i++)
      if (doom_ntohl(queuedpacket[i]->tic) > gametic) {
  newqueue = Z_Realloc(newqueue, ++newnum * sizeof *newqueue,
           PU_STATIC, NULL);
  newqueue[newnum-1] = queuedpacket[i];
      } else Z_Free(queuedpacket[i]);

    Z_Free(queuedpacket);
    numqueuedpackets = newnum; queuedpacket = newqueue;
  }
}
示例#2
0
void NetUpdate(void)
{
  static int lastmadetic;
  if (isExtraDDisplay)
    return;
  if (server) { // Receive network packets
    size_t recvlen;
    packet_header_t *packet = Z_Malloc(10000, PU_STATIC, NULL);
    while ((recvlen = I_GetPacket(packet, 10000))) {
      switch(packet->type) {
      case PKT_TICS:
  {
    uint8_t *p = (void*)(packet+1);
    int tics = *p++;
    unsigned long ptic = doom_ntohl(packet->tic);
    if (ptic > (unsigned)remotetic) { // Missed some
      packet_set(packet, PKT_RETRANS, remotetic);
      *(uint8_t*)(packet+1) = consoleplayer;
      I_SendPacket(packet, sizeof(*packet)+1);
    } else {
      if (ptic + tics <= (unsigned)remotetic) break; // Will not improve things
      remotetic = ptic;
      while (tics--) {
        int players = *p++;
        while (players--) {
            int n = *p++;
            RawToTic(&netcmds[n][remotetic%BACKUPTICS], p);
            p += sizeof(ticcmd_t);
        }
        remotetic++;
      }
    }
  }
  break;
      case PKT_RETRANS: // Resend request
          remotesend = doom_ntohl(packet->tic);
          break;
      case PKT_DOWN: // Server downed
  {
    int j;
    for (j=0; j<MAXPLAYERS; j++)
      if (j != consoleplayer) playeringame[j] = FALSE;
    server = FALSE;
    doom_printf("Server is down\nAll other players are no longer in the game\n");
  }
  break;
      case PKT_EXTRA: // Misc stuff
      case PKT_QUIT: // Player quit
  // Queue packet to be processed when its tic time is reached
  queuedpacket = Z_Realloc(queuedpacket, ++numqueuedpackets * sizeof *queuedpacket,
         PU_STATIC, NULL);
  queuedpacket[numqueuedpackets-1] = Z_Malloc(recvlen, PU_STATIC, NULL);
  memcpy(queuedpacket[numqueuedpackets-1], packet, recvlen);
  break;
      case PKT_BACKOFF:
        /* cph 2003-09-18 -
	 * The server sends this when we have got ahead of the other clients. We should
	 * stall the input side on this client, to allow other clients to catch up.
	 */
        lastmadetic++;
	break;
      default: // Other packet, unrecognised or redundant
  break;
      }
    }
    Z_Free(packet);
  }
  { // Build new ticcmds
    int newtics = I_GetTime() - lastmadetic;
    newtics = (newtics > 0 ? newtics : 0);
    lastmadetic += newtics;
    if (ffmap) newtics++;
    while (newtics--) {
      I_StartTic();
      if (maketic - gametic > BACKUPTICS/2) break;
      G_BuildTiccmd(&localcmds[maketic%BACKUPTICS]);
      maketic++;
    }
    if (server && maketic > remotesend) { // Send the tics to the server
      int sendtics;
      remotesend -= xtratics;
      if (remotesend < 0) remotesend = 0;
      sendtics = maketic - remotesend;
      {
  size_t pkt_size = sizeof(packet_header_t) + 2 + sendtics * sizeof(ticcmd_t);
  packet_header_t *packet = Z_Malloc(pkt_size, PU_STATIC, NULL);

  packet_set(packet, PKT_TICC, maketic - sendtics);
  *(uint8_t*)(packet+1) = sendtics;
  *(((uint8_t*)(packet+1))+1) = consoleplayer;
  {
    void *tic = ((uint8_t*)(packet+1)) +2;
    while (sendtics--) {
      TicToRaw(tic, &localcmds[remotesend++%BACKUPTICS]);
      tic = (uint8_t *)tic + sizeof(ticcmd_t);
    }
  }
  I_SendPacket(packet, pkt_size);
  Z_Free(packet);
      }
    }
  }
}
示例#3
0
void udp_receive(int s) {
  size_t len = 1024;
  packet_header_t *p = malloc(len);
  int rc;
  
  rc = read(s,p,len);
  if (rc < 0) {
    fprintf(stderr,"read(udp): %s\n", strerror(errno));
    exit(-2);
  }
  if (rc > 0) {
    switch (p->type) {
	    case PKT_SETUP:
		    {
			    struct setup_packet_s *sinfo = (void*)(p+1);
			    consoleplayer = sinfo->yourplayer;
			    send_udp_packet(PKT_GO,0,NULL,0);
			    write(ipxs,"\xff\xff\xff\xff\x00\x00\x00\x00\x02\x00\x02\x00\x00\x00\x00\x00",16);
		    }
		    break;
	    case PKT_GO:
		    {
			    ipxpacket_t pkt;
			    memset(&pkt,0,sizeof(pkt));
			    pkt.tic = ipxcounter++;
			    pkt.u.d.player = consoleplayer^1;
			    pkt.u.d.starttic = 0;
			    pkt.u.d.numtics = 0;
			    pkt.u.d.retransmitfrom = 0;
			    pkt.u.d.checksum = NetbufferChecksum(&pkt.u.d.retransmitfrom, 4);
			    write(ipxs,&pkt,16);
		    }
		    break;
	    case PKT_TICS:
		    {
			    ipxpacket_t pkt;
			    int tic = doom_ntohl(p->tic);
			    byte *pp = (void*)(p+1);
			    int tics = *pp++;
			    memset(&pkt,0,sizeof(pkt));
			    size_t len;

			    pkt.tic = ipxcounter++;
			    pkt.u.d.starttic = tic;
			    pkt.u.d.player = (consoleplayer == 0 ? 1 : 0);
			    pkt.u.d.numtics = tics;

			    for (int t=0; t<tics; t++) {
			      int players = *pp++;
			      for (int i=0; i<players; i++) {
				if (*pp++ == pkt.u.d.player)
				  RawToTic(&pkt.u.d.cmds[t],pp);
				pp += sizeof(ticcmd_t);
			      }
			    }
			    pkt.u.d.retransmitfrom = 0;
			    len = 12+tics*sizeof(ticcmd_t);
			    len = (len+7)&0xff8; // round up to next 16
			    pkt.u.d.checksum = NetbufferChecksum(&pkt.u.d.retransmitfrom, len-8);
			    write(ipxs,&pkt,len);
		    }
    }
  }
}