ref: bef4378c5cac18cea163dcdd6aea424e08e56ebf
dir: /doom-udpip/
diff 790a516884e45ee2a3a11b915f5e125a0ccb02ca uncommitted --- a/sys/src/games/doom/i_net.c +++ b/sys/src/games/doom/i_net.c @@ -20,142 +20,296 @@ // //----------------------------------------------------------------------------- -static const char -rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $"; - #include "doomdef.h" #include "doomstat.h" - -// #include "i_system.h" -// #include "d_event.h" -#include "d_net.h" +#include <bio.h> +#include <ndb.h> +#include <ip.h> +#include <thread.h> #include "m_argv.h" - +#include "i_system.h" +#include "d_net.h" #include "i_net.h" +#include "w_wad.h" +typedef struct Addr Addr; -// -// I_InitNetwork -// -void I_InitNetwork (void) +enum{ + HDRSZ = 16+16+16+2+2 /* sizeof Udphdr w/o padding */ +}; + +static char lsrv[6] = "666"; + +struct Addr{ + Udphdr h; + char srv[6]; /* convenience */ + int ready; /* is connected to udp!*!lsrv */ + long called; +}; +static Addr raddr[MAXNETNODES]; + +static int ucfd; +static int udfd; +static int upfd[2]; +static int upid; + + +static void +conreq(doomdata_t *d) { -printf("PORTME i_net.c I_InitNetwork (use 9P)\n"); + int fd; + long t; + char ip[64]; + Addr *p; - doomcom = malloc (sizeof(*doomcom)); - memset (doomcom, 0, sizeof(*doomcom)); + p = &raddr[doomcom->remotenode]; - /* set up for network */ - doomcom->ticdup = 1; - doomcom->extratics = 0; + t = time(nil); + if(t - p->called < 1) + return; -// netsend = PacketSend; -// netget = PacketGet; -// netgame = true; + snprint(ip, sizeof ip, "%I", p->h.raddr); + if((fd = dial(netmkaddr(ip, "udp", p->srv), lsrv, nil, nil)) < 0) + sysfatal("dial: %r"); + if(write(fd, d, doomcom->datalength) != doomcom->datalength) + sysfatal("conreq: %r"); + close(fd); + p->called = t; +} - /* parse player number and host list */ -// doomcom->consoleplayer = myargv[i+1][0]-'1'; +static void +dsend(void) +{ + int i; + uchar buf[HDRSZ+sizeof(doomdata_t)]; + doomdata_t d; - doomcom->numnodes = 1; // this node for sure + hnputl(&d.checksum, netbuffer->checksum); + d.player = netbuffer->player; + d.retransmitfrom = netbuffer->retransmitfrom; + d.starttic = netbuffer->starttic; + d.numtics = netbuffer->numtics; - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes; + for(i = 0; i < netbuffer->numtics; i++){ + d.cmds[i].forwardmove = netbuffer->cmds[i].forwardmove; + d.cmds[i].sidemove = netbuffer->cmds[i].sidemove; + hnputs(&d.cmds[i].angleturn, netbuffer->cmds[i].angleturn); + hnputs(&d.cmds[i].consistancy, netbuffer->cmds[i].consistancy); + d.cmds[i].chatchar = netbuffer->cmds[i].chatchar; + d.cmds[i].buttons = netbuffer->cmds[i].buttons; + } -/* - boolean trueval = true; - int i; - int p; - struct hostent* hostentry; // host information entry - - doomcom = malloc (sizeof (*doomcom) ); - memset (doomcom, 0, sizeof(*doomcom) ); - - // set up for network - i = M_CheckParm ("-dup"); - if (i && i< myargc-1) - { - doomcom->ticdup = myargv[i+1][0]-'0'; - if (doomcom->ticdup < 1) - doomcom->ticdup = 1; - if (doomcom->ticdup > 9) - doomcom->ticdup = 9; - } - else - doomcom-> ticdup = 1; - - if (M_CheckParm ("-extratic")) - doomcom-> extratics = 1; - else - doomcom-> extratics = 0; - - p = M_CheckParm ("-port"); - if (p && p<myargc-1) - { - DOOMPORT = atoi (myargv[p+1]); - printf ("using alternate port %i\n",DOOMPORT); - } - - // parse network game options, - // -net <consoleplayer> <host> <host> ... - i = M_CheckParm ("-net"); - if (!i) - { - // single player game - netgame = false; - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes = 1; - doomcom->deathmatch = false; - doomcom->consoleplayer = 0; - return; - } + if(!raddr[doomcom->remotenode].ready){ + conreq(&d); + return; + } + memcpy(buf, &raddr[doomcom->remotenode].h, HDRSZ); + memcpy(buf+HDRSZ, &d, sizeof d); - netsend = PacketSend; - netget = PacketGet; - netgame = true; + i = doomcom->datalength + HDRSZ; + if(write(udfd, buf, i) != i) + sysfatal("dsend: %r"); +} - // parse player number and host list - doomcom->consoleplayer = myargv[i+1][0]-'1'; +static void +drecv(void) +{ + int n; + ushort i; + doomdata_t d; - doomcom->numnodes = 1; // this node for sure - - i++; - while (++i < myargc && myargv[i][0] != '-') - { - sendaddress[doomcom->numnodes].sin_family = AF_INET; - sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT); - if (myargv[i][0] == '.') - { - sendaddress[doomcom->numnodes].sin_addr.s_addr - = inet_addr (myargv[i]+1); + if(filelength(upfd[1]) < 1){ + doomcom->remotenode = -1; + return; } - else - { - hostentry = gethostbyname (myargv[i]); - if (!hostentry) - I_Error ("gethostbyname: couldn't find %s", myargv[i]); - sendaddress[doomcom->numnodes].sin_addr.s_addr - = *(int *)hostentry->h_addr_list[0]; + if((n = read(upfd[1], &d, sizeof d)) <= 0 + || read(upfd[1], &i, sizeof i) <= 0) + sysfatal("drecv: %r"); + + doomcom->remotenode = i; + doomcom->datalength = n; + + /* FIXME: proper read/write from/to struct */ + netbuffer->checksum = nhgetl(&d.checksum); + netbuffer->player = d.player; + netbuffer->retransmitfrom = d.retransmitfrom; + netbuffer->starttic = d.starttic; + netbuffer->numtics = d.numtics; + for(i = 0; i < netbuffer->numtics; i++){ + netbuffer->cmds[i].forwardmove = d.cmds[i].forwardmove; + netbuffer->cmds[i].sidemove = d.cmds[i].sidemove; + netbuffer->cmds[i].angleturn = nhgets(&d.cmds[i].angleturn); + netbuffer->cmds[i].consistancy = nhgets(&d.cmds[i].consistancy); + netbuffer->cmds[i].chatchar = d.cmds[i].chatchar; + netbuffer->cmds[i].buttons = d.cmds[i].buttons; } - doomcom->numnodes++; - } - - doomcom->id = DOOMCOM_ID; - doomcom->numplayers = doomcom->numnodes; -*/ } +static void +uproc(void*) +{ + int n; + ushort i; + uchar buf[HDRSZ+sizeof(doomdata_t)]; + Udphdr h; -void I_NetCmd (void) + upid = getpid(); + for(;;){ + if((n = read(udfd, buf, sizeof buf)) <= 0) + break; + memcpy(&h, buf, HDRSZ); + + for(i = 0; i < doomcom->numnodes; i++) + if(equivip6(h.raddr, raddr[i].h.raddr) + && nhgets(h.rport) == nhgets(raddr[i].h.rport)) + break; + if(i == doomcom->numnodes) + continue; /* ignore messages from strangers */ + if(!raddr[i].ready){ /* FIXME: urgh */ + raddr[i].ready++; + memcpy(&raddr[i].h, &h, sizeof h); + } + + if(write(upfd[0], buf+HDRSZ, n - HDRSZ) != n - HDRSZ + || write(upfd[0], &i, sizeof i) != sizeof i) + break; + } +} + +void +I_NetCmd(void) { -/* - if (doomcom->command == CMD_SEND) - { - netsend (); - } - else if (doomcom->command == CMD_GET) - { - netget (); - } - else - I_Error ("Bad net cmd: %i\n",doomcom->command); -*/ + if(doomcom->command == CMD_SEND) + dsend(); + else if(doomcom->command == CMD_GET) + drecv(); + else + I_Error("invalid netcmd %d", doomcom->command); +} + +void +I_ShutdownNet(void) +{ + postnote(PNPROC, upid, "shutdown"); + close(upfd[0]); + close(upfd[1]); + close(udfd); + close(ucfd); +} + +static void +initudp(void) +{ + char data[64], adir[40]; + + /* FIXME */ + //if(myipaddr(raddr[0].h.raddr, nil) < 0) + // sysfatal("myipaddr: %r"); + + if((ucfd = announce(netmkaddr("*", "udp", lsrv), adir)) < 0) + sysfatal("announce: %r"); + if(fprint(ucfd, "headers") < 0) + sysfatal("failed to set headers mode: %r"); + snprint(data, sizeof data, "%s/data", adir); + if((udfd = open(data, ORDWR)) < 0) + sysfatal("open: %r"); + + if(pipe(upfd) < 0) + sysfatal("pipe: %r"); + if(procrfork(uproc, nil, mainstacksize, RFFDG) < 0) + sysfatal("procrfork: %r"); +} + +static void +csip(char *s, Addr *a) /* raddr!rsrv */ +{ + int fd, n; + char buf[128], *f[3]; + + /* FIXME: get netmnt... */ + + if((fd = open("/net/cs", ORDWR)) < 0) + sysfatal("open: %r"); + + snprint(buf, sizeof buf, "udp!%s", s); + n = strlen(buf); + if(write(fd, buf, n) != n) + sysfatal("translating %s: %r", s); + + seek(fd, 0, 0); + if((n = read(fd, buf, sizeof(buf)-1)) <= 0) + sysfatal("reading cs tables: %r"); + buf[n] = 0; + close(fd); + + if(getfields(buf, f, 3, 1, " !") < 2) + sysfatal("bad cs entry %s", buf); + + if(parseip(a->h.raddr, f[1]) < 0) + sysfatal("parseip: %r"); + hnputs(a->h.rport, atoi(f[2])); /* FIXME */ + strncpy(a->srv, f[2], sizeof(a->srv)-1); +} + +static int +netopts(void) +{ + int i; + + if((i = M_CheckParm("-dup")) && i < myargc - 1){ + doomcom->ticdup = myargv[i+1][0] - '0'; + if(doomcom->ticdup < 1) + doomcom->ticdup = 1; + if(doomcom->ticdup > 9) + doomcom->ticdup = 9; + } + + if(M_CheckParm("-extratic")) + doomcom->extratics = 1; + + if((i = M_CheckParm("-srv")) && i < myargc - 1) + strncpy(lsrv, myargv[i+1], sizeof(lsrv)-1); + + /* [0-3], default 0; player 0 is special */ + if((i = M_CheckParm("-pn")) && i < myargc - 1) + doomcom->consoleplayer = myargv[i+1][0] - '0'; + + /* FIXME: d_net.c: don't use remoteaddr=0 as special case (max+1?) */ + /* remote host address list: -net raddr!rsrv.. */ + if((i = M_CheckParm("-net")) == 0){ + /* single player game */ + doomcom->id = DOOMCOM_ID; + doomcom->numplayers = doomcom->numnodes = 1; + doomcom->deathmatch = false; + netgame = false; + return -1; + } + doomcom->numnodes++; /* raddr[0] is special cased because ??? */ + while(++i < myargc && myargv[i][0] != '-'){ + csip(myargv[i], &raddr[doomcom->numnodes]); + doomcom->numnodes++; + } + + return 0; +} + +void +I_InitNetwork(void) +{ + doomcom = malloc(sizeof *doomcom); + memset(doomcom, 0, sizeof *doomcom); + + doomcom->ticdup = 1; + doomcom->extratics = 0; + if(netopts() < 0) + return; + if(doomcom->numnodes < 2) + I_Error("netgame with a single node"); + doomcom->id = DOOMCOM_ID; + doomcom->numplayers = doomcom->numnodes; + + fmtinstall('I', eipfmt); + initudp(); + + netgame = true; } --- a/sys/src/games/doom/i_net.h +++ b/sys/src/games/doom/i_net.h @@ -35,6 +35,7 @@ void I_InitNetwork (void); void I_NetCmd (void); +void I_ShutdownNet (void); #endif --- a/sys/src/games/doom/i_system.c +++ b/sys/src/games/doom/i_system.c @@ -6,6 +6,7 @@ #include "i_system.h" #include "i_sound.h" #include "i_video.h" +#include "i_net.h" #include "d_main.h" #include "d_net.h" @@ -42,6 +43,7 @@ void I_Quit (void) { D_QuitNetGame (); + I_ShutdownNet(); I_ShutdownSound(); I_ShutdownMusic(); M_SaveDefaults (); @@ -86,6 +88,7 @@ G_CheckDemoStatus(); D_QuitNetGame (); + I_ShutdownNet(); I_ShutdownGraphics(); exits("I_Error"); --- a/sys/src/games/doom/w_wad.h +++ b/sys/src/games/doom/w_wad.h @@ -67,6 +67,8 @@ void* W_CacheLumpNum (int lump, int tag); void* W_CacheLumpName (char* name, int tag); +vlong filelength(int); + #endif //----------------------------------------------------------------------------- //