boolean HGetPacket (void) { if (reboundpacket) { *netbuffer = reboundstore; doomcom->remotenode = 0; reboundpacket = false; return true; } if (!netgame) return false; if (demoplayback) return false; doomcom->command = CMD_GET; I_NetCmd (); if (doomcom->remotenode == -1) return false; if (doomcom->datalength != NetbufferSize ()) { if (debugfile) fprintf (debugfile,"bad packet length %i\n",doomcom->datalength); return false; } if (NetbufferChecksum () != (netbuffer->checksum&NCMD_CHECKSUM) ) { if (debugfile) fprintf (debugfile,"bad packet checksum\n"); return false; } if (debugfile) { int realretrans; int i; if (netbuffer->checksum & NCMD_SETUP) fprintf (debugfile,"setup packet\n"); else { if (netbuffer->checksum & NCMD_RETRANSMIT) realretrans = ExpandTics (netbuffer->retransmitfrom); else realretrans = -1; fprintf (debugfile,"get %i = (%i + %i, R %i)[%i] ",doomcom->remotenode, ExpandTics(netbuffer->starttic),netbuffer->numtics, realretrans, doomcom->datalength); for (i=0 ; i<doomcom->datalength ; i++) fprintf (debugfile,"%i ",((byte *)netbuffer)[i]); fprintf (debugfile,"\n"); } } return true; }
// // HSendPacket // void HSendPacket (int node, int flags ) { netbuffer->checksum = NetbufferChecksum () | flags; if (!node) { reboundstore = *netbuffer; reboundpacket = true; return; } if (demoplayback) return; if (!netgame) I_Error ("Tried to transmit to another node"); doomcom->command = CMD_SEND; doomcom->remotenode = node; doomcom->datalength = NetbufferSize (); #if 0 // AJH HACK if (debugfile) { int i; int realretrans; if (netbuffer->checksum & NCMD_RETRANSMIT) realretrans = ExpandTics (netbuffer->retransmitfrom); else realretrans = -1; I_DBGprintf("send (%i + %i, R %i) [%i] ", ExpandTics(netbuffer->starttic), netbuffer->numtics, realretrans, doomcom->datalength); for (i=0 ; i<doomcom->datalength ; i++) I_DBGprintf("%i ",((byte *)netbuffer)[i]); I_DBGprintf("\n"); } #endif I_NetCmd (); }
void ipx_receive(int s) { ipxpacket_t buf; int rc; struct sockaddr from; size_t sl = sizeof(from); rc = recvfrom(s,&buf,sizeof buf,0,&from,&sl); if (rc == -1) { fprintf(stderr,"read(ipx): %s\n", strerror(errno)); exit(-2); } if (rc > 0) { if (buf.tic == -1) { // Setup packet if (!connected++) { connect(s,&from,sl); send_udp_packet(PKT_INIT,0,NULL,0); } } else { if (buf.u.d.checksum & NCMD_SETUP) { printf("setup packet, dropped\n"); } else if (buf.u.d.checksum & NCMD_EXIT) { send_udp_packet(PKT_QUIT,buf.u.d.starttic,NULL,0); exit(0); } else if ((buf.u.d.checksum & NCMD_CHECKSUM) == buf.u.d.checksum) { // No flags, normal game packet char outbuf[100]; int tics; outbuf[0] = tics = buf.u.d.numtics; outbuf[1] = buf.u.d.player; for (int i=0; i< tics; i++) TicToRaw(outbuf+2+i*sizeof(ticcmd_t),&buf.u.d.cmds[i]); send_udp_packet(PKT_TICC, ExpandTics(buf.u.d.starttic, basetic), outbuf, 2+tics*sizeof(ticcmd_t)); } } } }
static void DebugPrintpacket(const 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: case PT_ASKINFOVIAMS: fprintf(debugfile, " time %u\n", (tic_t)LONG(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 %u ply %d tics %d ntxtcmd %s\n ", (UINT32)ExpandTics(netbuffer->u.serverpak.starttic), netbuffer->u.serverpak.numslots, netbuffer->u.serverpak.numtics, sizeu1((size_t)(&((UINT8 *)netbuffer)[doomcom->datalength] - (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots*netbuffer->u.serverpak.numtics]))); fprintfstring((char *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots*netbuffer->u.serverpak.numtics],(size_t)( &((UINT8 *)netbuffer)[doomcom->datalength] - (UINT8 *)&netbuffer->u.serverpak.cmds[netbuffer->u.serverpak.numslots*netbuffer->u.serverpak.numtics])); break; case PT_CLIENTCMD: case PT_CLIENT2CMD: case PT_CLIENTMIS: case PT_CLIENT2MIS: case PT_NODEKEEPALIVE: case PT_NODEKEEPALIVEMIS: fprintf(debugfile, " tic %4u resendfrom %u\n", (UINT32)ExpandTics(netbuffer->u.clientpak.client_tic), (UINT32)ExpandTics (netbuffer->u.clientpak.resendfrom)); break; case PT_TEXTCMD: case PT_TEXTCMD2: fprintf(debugfile, " length %d\n ", netbuffer->u.textcmd[0]); fprintfstring((char *)netbuffer->u.textcmd+1, netbuffer->u.textcmd[0]); break; case PT_SERVERCFG: fprintf(debugfile, " playerslots %d clientnode %d serverplayer %d " "gametic %u gamestate %d gametype %d modifiedgame %d\n", netbuffer->u.servercfg.totalslotnum, netbuffer->u.servercfg.clientnode, netbuffer->u.servercfg.serverplayer, (UINT32)LONG(netbuffer->u.servercfg.gametic), netbuffer->u.servercfg.gamestate, netbuffer->u.servercfg.gametype, netbuffer->u.servercfg.modifiedgame); break; case PT_SERVERINFO: fprintf(debugfile, " '%s' player %d/%d, map %s, filenum %d, time %u \n", netbuffer->u.serverinfo.servername, netbuffer->u.serverinfo.numberofplayer, netbuffer->u.serverinfo.maxplayer, netbuffer->u.serverinfo.mapname, netbuffer->u.serverinfo.fileneedednum, (UINT32)LONG(netbuffer->u.serverinfo.time)); fprintfstring((char *)netbuffer->u.serverinfo.fileneeded, (UINT8)((UINT8 *)netbuffer + doomcom->datalength - (UINT8 *)netbuffer->u.serverinfo.fileneeded)); break; case PT_SERVERREFUSE: fprintf(debugfile, " reason %s\n", netbuffer->u.serverrefuse.reason); break; case PT_FILEFRAGMENT: fprintf(debugfile, " fileid %d datasize %d position %u\n", netbuffer->u.filetxpak.fileid, (UINT16)SHORT(netbuffer->u.filetxpak.size), (UINT32)LONG(netbuffer->u.filetxpak.position)); break; case PT_REQUESTFILE: default: // write as a raw packet fprintfstring((char *)netbuffer->u.textcmd, (UINT8)((UINT8 *)netbuffer + doomcom->datalength - (UINT8 *)netbuffer->u.textcmd)); break; } }
void GetPackets (void) { int netconsole; int netnode; ticcmd_t *src, *dest; int realend; int realstart; while ( HGetPacket() ) { if (netbuffer->checksum & NCMD_SETUP) continue; // extra setup packet netconsole = netbuffer->player & ~PL_DRONE; netnode = doomcom->remotenode; // to save bytes, only the low byte of tic numbers are sent // Figure out what the rest of the bytes are realstart = ExpandTics (netbuffer->starttic); realend = (realstart+netbuffer->numtics); // check for exiting the game if (netbuffer->checksum & NCMD_EXIT) { if (!nodeingame[netnode]) continue; nodeingame[netnode] = false; playeringame[netconsole] = false; strcpy (exitmsg, "Player 1 left the game"); exitmsg[7] += netconsole; players[consoleplayer].message = exitmsg; if (demorecording) G_CheckDemoStatus (); continue; } // check for a remote game kill if (netbuffer->checksum & NCMD_KILL) I_Error ("Killed by network driver"); nodeforplayer[netconsole] = netnode; // check for retransmit request if ( resendcount[netnode] <= 0 && (netbuffer->checksum & NCMD_RETRANSMIT) ) { resendto[netnode] = ExpandTics(netbuffer->retransmitfrom); if (debugfile) fprintf (debugfile,"retransmit from %i\n", resendto[netnode]); resendcount[netnode] = RESENDCOUNT; } else resendcount[netnode]--; // check for out of order / duplicated packet if (realend == nettics[netnode]) continue; if (realend < nettics[netnode]) { if (debugfile) fprintf (debugfile, "out of order packet (%i + %i)\n" , realstart,netbuffer->numtics); continue; } // check for a missed packet if (realstart > nettics[netnode]) { // stop processing until the other system resends the missed tics if (debugfile) fprintf (debugfile, "missed tics from %i (%i - %i)\n", netnode, realstart, nettics[netnode]); remoteresend[netnode] = true; continue; } // update command store from the packet { int start; remoteresend[netnode] = false; start = nettics[netnode] - realstart; src = &netbuffer->cmds[start]; while (nettics[netnode] < realend) { dest = &netcmds[netconsole][nettics[netnode]%BACKUPTICS]; nettics[netnode]++; *dest = *src; src++; } } } }