doom

a minimalistic implementation of doom
git clone git://ssnf.xyz/doom
Log | Files | Refs

i_net.c (6490B)


      1 #include <stdlib.h>
      2 #include <string.h>
      3 #include <stdio.h>
      4 
      5 #include <sys/socket.h>
      6 #include <netinet/in.h>
      7 #include <arpa/inet.h>
      8 #include <errno.h>
      9 #include <unistd.h>
     10 #include <netdb.h>
     11 #include <sys/ioctl.h>
     12 
     13 #include "i_system.h"
     14 #include "d_event.h"
     15 #include "d_net.h"
     16 #include "m_argv.h"
     17 
     18 #include "doomstat.h"
     19 
     20 #include "i_net.h"
     21 
     22 /*
     23 #define ntohl(x) \
     24         ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
     25                              (((unsigned long int)(x) & 0x0000ff00U) <<  8) | \
     26                              (((unsigned long int)(x) & 0x00ff0000U) >>  8) | \
     27                              (((unsigned long int)(x) & 0xff000000U) >> 24)))
     28 
     29 #define ntohs(x) \
     30         ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
     31                               (((unsigned short int)(x) & 0xff00) >> 8))) \
     32 	  
     33 #define htonl(x) ntohl(x)
     34 #define htons(x) ntohs(x)
     35 */
     36 
     37 void	NetSend (void);
     38 boolean NetListen (void);
     39 
     40 
     41 
     42 
     43 
     44 
     45 int	DOOMPORT =	(IPPORT_USERRESERVED +0x1d );
     46 
     47 int			sendsocket;
     48 int			insocket;
     49 
     50 struct	sockaddr_in	sendaddress[MAXNETNODES];
     51 
     52 void	(*netget) (void);
     53 void	(*netsend) (void);
     54 
     55 
     56 
     57 
     58 
     59 int UDPsocket (void)
     60 {
     61     int	s;
     62 	
     63     
     64     s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     65     if (s<0)
     66 	I_Error ("can't create socket: %s",strerror(errno));
     67 		
     68     return s;
     69 }
     70 
     71 
     72 
     73 
     74 void
     75 BindToLocalPort
     76 ( int	s,
     77   int	port )
     78 {
     79     int			v;
     80     struct sockaddr_in	address;
     81 	
     82     memset (&address, 0, sizeof(address));
     83     address.sin_family = AF_INET;
     84     address.sin_addr.s_addr = INADDR_ANY;
     85     address.sin_port = port;
     86 			
     87     v = bind (s, (void *)&address, sizeof(address));
     88     if (v == -1)
     89 	I_Error ("BindToPort: bind: %s", strerror(errno));
     90 }
     91 
     92 
     93 
     94 
     95 
     96 void PacketSend (void)
     97 {
     98     int		c;
     99     doomdata_t	sw;
    100 				
    101     
    102     sw.checksum = htonl(netbuffer->checksum);
    103     sw.player = netbuffer->player;
    104     sw.retransmitfrom = netbuffer->retransmitfrom;
    105     sw.starttic = netbuffer->starttic;
    106     sw.numtics = netbuffer->numtics;
    107     for (c=0 ; c< netbuffer->numtics ; c++)
    108     {
    109 	sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove;
    110 	sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove;
    111 	sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn);
    112 	sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
    113 	sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
    114 	sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
    115     }
    116 		
    117     
    118     c = sendto (sendsocket , &sw, doomcom->datalength
    119 		,0,(void *)&sendaddress[doomcom->remotenode]
    120 		,sizeof(sendaddress[doomcom->remotenode]));
    121 	
    122     
    123     
    124 }
    125 
    126 
    127 
    128 
    129 
    130 void PacketGet (void)
    131 {
    132     int			i;
    133     int			c;
    134     struct sockaddr_in	fromaddress;
    135     unsigned int			fromlen;
    136     doomdata_t		sw;
    137 				
    138     fromlen = sizeof(fromaddress);
    139     c = recvfrom (insocket, &sw, sizeof(sw), 0, (struct sockaddr *)&fromaddress, &fromlen );
    140     if (c == -1 )
    141     {
    142 	if (errno != EWOULDBLOCK)
    143 	    I_Error ("GetPacket: %s",strerror(errno));
    144 	doomcom->remotenode = -1;		
    145 	return;
    146     }
    147 
    148     {
    149 	static int first=1;
    150 	if (first)
    151 	    printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1));
    152 	first = 0;
    153     }
    154 
    155     
    156     for (i=0 ; i<doomcom->numnodes ; i++)
    157 	if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr )
    158 	    break;
    159 
    160     if (i == doomcom->numnodes)
    161     {
    162 	
    163 	doomcom->remotenode = -1;		
    164 		return;
    165     }
    166 	
    167     doomcom->remotenode = i;			
    168     doomcom->datalength = c;
    169 	
    170     
    171     netbuffer->checksum = ntohl(sw.checksum);
    172     netbuffer->player = sw.player;
    173     netbuffer->retransmitfrom = sw.retransmitfrom;
    174     netbuffer->starttic = sw.starttic;
    175     netbuffer->numtics = sw.numtics;
    176 
    177     for (c=0 ; c< netbuffer->numtics ; c++)
    178     {
    179 	netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove;
    180 	netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove;
    181 	netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn);
    182 	netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
    183 	netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
    184 	netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
    185     }
    186 }
    187 
    188 
    189 
    190 int GetLocalAddress (void)
    191 {
    192     char		hostname[1024];
    193     struct hostent*	hostentry;	
    194     int			v;
    195 
    196     
    197     v = gethostname (hostname, sizeof(hostname));
    198     if (v == -1)
    199 	I_Error ("GetLocalAddress : gethostname: errno %d",errno);
    200 	
    201     hostentry = gethostbyname (hostname);
    202     if (!hostentry)
    203 	I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
    204 		
    205     return *(int *)hostentry->h_addr_list[0];
    206 }
    207 
    208 
    209 
    210 
    211 
    212 void I_InitNetwork (void)
    213 {
    214     boolean		trueval = true;
    215     int			i;
    216     int			p;
    217     struct hostent*	hostentry;	
    218 	
    219     doomcom = malloc (sizeof (*doomcom) );
    220     memset (doomcom, 0, sizeof(*doomcom) );
    221     
    222     
    223     i = M_CheckParm ("-dup");
    224     if (i && i< myargc-1)
    225     {
    226 	doomcom->ticdup = myargv[i+1][0]-'0';
    227 	if (doomcom->ticdup < 1)
    228 	    doomcom->ticdup = 1;
    229 	if (doomcom->ticdup > 9)
    230 	    doomcom->ticdup = 9;
    231     }
    232     else
    233 	doomcom-> ticdup = 1;
    234 	
    235     if (M_CheckParm ("-extratic"))
    236 	doomcom-> extratics = 1;
    237     else
    238 	doomcom-> extratics = 0;
    239 		
    240     p = M_CheckParm ("-port");
    241     if (p && p<myargc-1)
    242     {
    243 	DOOMPORT = atoi (myargv[p+1]);
    244 	printf ("using alternate port %i\n",DOOMPORT);
    245     }
    246     
    247     
    248     
    249     i = M_CheckParm ("-net");
    250     if (!i)
    251     {
    252 	
    253 	netgame = false;
    254 	doomcom->id = DOOMCOM_ID;
    255 	doomcom->numplayers = doomcom->numnodes = 1;
    256 	doomcom->deathmatch = false;
    257 	doomcom->consoleplayer = 0;
    258 	return;
    259     }
    260 
    261     netsend = PacketSend;
    262     netget = PacketGet;
    263     netgame = true;
    264 
    265     
    266     doomcom->consoleplayer = myargv[i+1][0]-'1';
    267 
    268     doomcom->numnodes = 1;	
    269 	
    270     i++;
    271     while (++i < myargc && myargv[i][0] != '-')
    272     {
    273 	sendaddress[doomcom->numnodes].sin_family = AF_INET;
    274 	sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
    275 	if (myargv[i][0] == '.')
    276 	{
    277 	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
    278 		= inet_addr (myargv[i]+1);
    279 	}
    280 	else
    281 	{
    282 	    hostentry = gethostbyname (myargv[i]);
    283 	    if (!hostentry)
    284 		I_Error ("gethostbyname: couldn't find %s", myargv[i]);
    285 	    sendaddress[doomcom->numnodes].sin_addr.s_addr 
    286 		= *(int *)hostentry->h_addr_list[0];
    287 	}
    288 	doomcom->numnodes++;
    289     }
    290 	
    291     doomcom->id = DOOMCOM_ID;
    292     doomcom->numplayers = doomcom->numnodes;
    293     
    294     
    295     insocket = UDPsocket ();
    296     BindToLocalPort (insocket,htons(DOOMPORT));
    297     ioctl (insocket, FIONBIO, &trueval);
    298 
    299     sendsocket = UDPsocket ();
    300 }
    301 
    302 
    303 void I_NetCmd (void)
    304 {
    305     if (doomcom->command == CMD_SEND)
    306     {
    307 	netsend ();
    308     }
    309     else if (doomcom->command == CMD_GET)
    310     {
    311 	netget ();
    312     }
    313     else
    314 	I_Error ("Bad net cmd: %i\n",doomcom->command);
    315 }
    316