|
|
1.1 root 1: // Emacs style mode select -*- C++ -*-
2: //-----------------------------------------------------------------------------
3: //
4: // $Id:$
5: //
6: // Copyright (C) 1993-1996 by id Software, Inc.
7: //
8: // This program is free software; you can redistribute it and/or
9: // modify it under the terms of the GNU General Public License
10: // as published by the Free Software Foundation; either version 2
11: // of the License, or (at your option) any later version.
12: //
13: // This program is distributed in the hope that it will be useful,
14: // but WITHOUT ANY WARRANTY; without even the implied warranty of
15: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: // GNU General Public License for more details.
17: //
18: // $Log:$
19: //
20: // DESCRIPTION:
21: //
22: //-----------------------------------------------------------------------------
23:
24: static const char
25: rcsid[] = "$Id: m_bbox.c,v 1.1 1997/02/03 22:45:10 b1 Exp $";
26:
27: #include <stdlib.h>
28: #include <string.h>
29: #include <stdio.h>
30:
31: #include <sys/socket.h>
32: #include <netinet/in.h>
33: #include <arpa/inet.h>
34: #include <errno.h>
35: #include <unistd.h>
36: #include <netdb.h>
37: #include <sys/ioctl.h>
38:
39: #include "i_system.h"
40: #include "d_event.h"
41: #include "d_net.h"
42: #include "m_argv.h"
43:
44: #include "doomstat.h"
45:
46: #ifdef __GNUG__
47: #pragma implementation "i_net.h"
48: #endif
49: #include "i_net.h"
50:
51:
52:
53:
54:
55: // For some odd reason...
56: #define ntohl(x) \
57: ((unsigned long int)((((unsigned long int)(x) & 0x000000ffU) << 24) | \
58: (((unsigned long int)(x) & 0x0000ff00U) << 8) | \
59: (((unsigned long int)(x) & 0x00ff0000U) >> 8) | \
60: (((unsigned long int)(x) & 0xff000000U) >> 24)))
61:
62: #define ntohs(x) \
63: ((unsigned short int)((((unsigned short int)(x) & 0x00ff) << 8) | \
64: (((unsigned short int)(x) & 0xff00) >> 8))) \
65:
66: #define htonl(x) ntohl(x)
67: #define htons(x) ntohs(x)
68:
69: void NetSend (void);
70: boolean NetListen (void);
71:
72:
73: //
74: // NETWORKING
75: //
76:
77: int DOOMPORT = (IPPORT_USERRESERVED +0x1d );
78:
79: int sendsocket;
80: int insocket;
81:
82: struct sockaddr_in sendaddress[MAXNETNODES];
83:
84: void (*netget) (void);
85: void (*netsend) (void);
86:
87:
88: //
89: // UDPsocket
90: //
91: int UDPsocket (void)
92: {
93: int s;
94:
95: // allocate a socket
96: s = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
97: if (s<0)
98: I_Error ("can't create socket: %s",strerror(errno));
99:
100: return s;
101: }
102:
103: //
104: // BindToLocalPort
105: //
106: void
107: BindToLocalPort
108: ( int s,
109: int port )
110: {
111: int v;
112: struct sockaddr_in address;
113:
114: memset (&address, 0, sizeof(address));
115: address.sin_family = AF_INET;
116: address.sin_addr.s_addr = INADDR_ANY;
117: address.sin_port = port;
118:
119: v = bind (s, (void *)&address, sizeof(address));
120: if (v == -1)
121: I_Error ("BindToPort: bind: %s", strerror(errno));
122: }
123:
124:
125: //
126: // PacketSend
127: //
128: void PacketSend (void)
129: {
130: int c;
131: doomdata_t sw;
132:
133: // byte swap
134: sw.checksum = htonl(netbuffer->checksum);
135: sw.player = netbuffer->player;
136: sw.retransmitfrom = netbuffer->retransmitfrom;
137: sw.starttic = netbuffer->starttic;
138: sw.numtics = netbuffer->numtics;
139: for (c=0 ; c< netbuffer->numtics ; c++)
140: {
141: sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove;
142: sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove;
143: sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn);
144: sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
145: sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
146: sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
147: }
148:
149: //printf ("sending %i\n",gametic);
150: c = sendto (sendsocket , &sw, doomcom->datalength
151: ,0,(void *)&sendaddress[doomcom->remotenode]
152: ,sizeof(sendaddress[doomcom->remotenode]));
153:
154: // if (c == -1)
155: // I_Error ("SendPacket error: %s",strerror(errno));
156: }
157:
158:
159: //
160: // PacketGet
161: //
162: void PacketGet (void)
163: {
164: int i;
165: int c;
166: struct sockaddr_in fromaddress;
167: int fromlen;
168: doomdata_t sw;
169:
170: fromlen = sizeof(fromaddress);
171: c = recvfrom (insocket, &sw, sizeof(sw), 0
172: , (struct sockaddr *)&fromaddress, &fromlen );
173: if (c == -1 )
174: {
175: if (errno != EWOULDBLOCK)
176: I_Error ("GetPacket: %s",strerror(errno));
177: doomcom->remotenode = -1; // no packet
178: return;
179: }
180:
181: {
182: static int first=1;
183: if (first)
184: printf("len=%d:p=[0x%x 0x%x] \n", c, *(int*)&sw, *((int*)&sw+1));
185: first = 0;
186: }
187:
188: // find remote node number
189: for (i=0 ; i<doomcom->numnodes ; i++)
190: if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr )
191: break;
192:
193: if (i == doomcom->numnodes)
194: {
195: // packet is not from one of the players (new game broadcast)
196: doomcom->remotenode = -1; // no packet
197: return;
198: }
199:
200: doomcom->remotenode = i; // good packet from a game player
201: doomcom->datalength = c;
202:
203: // byte swap
204: netbuffer->checksum = ntohl(sw.checksum);
205: netbuffer->player = sw.player;
206: netbuffer->retransmitfrom = sw.retransmitfrom;
207: netbuffer->starttic = sw.starttic;
208: netbuffer->numtics = sw.numtics;
209:
210: for (c=0 ; c< netbuffer->numtics ; c++)
211: {
212: netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove;
213: netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove;
214: netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn);
215: netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
216: netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
217: netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
218: }
219: }
220:
221:
222:
223: int GetLocalAddress (void)
224: {
225: char hostname[1024];
226: struct hostent* hostentry; // host information entry
227: int v;
228:
229: // get local address
230: v = gethostname (hostname, sizeof(hostname));
231: if (v == -1)
232: I_Error ("GetLocalAddress : gethostname: errno %d",errno);
233:
234: hostentry = gethostbyname (hostname);
235: if (!hostentry)
236: I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
237:
238: return *(int *)hostentry->h_addr_list[0];
239: }
240:
241:
242: //
243: // I_InitNetwork
244: //
245: void I_InitNetwork (void)
246: {
247: boolean trueval = true;
248: int i;
249: int p;
250: struct hostent* hostentry; // host information entry
251:
252: doomcom = malloc (sizeof (*doomcom) );
253: memset (doomcom, 0, sizeof(*doomcom) );
254:
255: // set up for network
256: i = M_CheckParm ("-dup");
257: if (i && i< myargc-1)
258: {
259: doomcom->ticdup = myargv[i+1][0]-'0';
260: if (doomcom->ticdup < 1)
261: doomcom->ticdup = 1;
262: if (doomcom->ticdup > 9)
263: doomcom->ticdup = 9;
264: }
265: else
266: doomcom-> ticdup = 1;
267:
268: if (M_CheckParm ("-extratic"))
269: doomcom-> extratics = 1;
270: else
271: doomcom-> extratics = 0;
272:
273: p = M_CheckParm ("-port");
274: if (p && p<myargc-1)
275: {
276: DOOMPORT = atoi (myargv[p+1]);
277: printf ("using alternate port %i\n",DOOMPORT);
278: }
279:
280: // parse network game options,
281: // -net <consoleplayer> <host> <host> ...
282: i = M_CheckParm ("-net");
283: if (!i)
284: {
285: // single player game
286: netgame = false;
287: doomcom->id = DOOMCOM_ID;
288: doomcom->numplayers = doomcom->numnodes = 1;
289: doomcom->deathmatch = false;
290: doomcom->consoleplayer = 0;
291: return;
292: }
293:
294: netsend = PacketSend;
295: netget = PacketGet;
296: netgame = true;
297:
298: // parse player number and host list
299: doomcom->consoleplayer = myargv[i+1][0]-'1';
300:
301: doomcom->numnodes = 1; // this node for sure
302:
303: i++;
304: while (++i < myargc && myargv[i][0] != '-')
305: {
306: sendaddress[doomcom->numnodes].sin_family = AF_INET;
307: sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
308: if (myargv[i][0] == '.')
309: {
310: sendaddress[doomcom->numnodes].sin_addr.s_addr
311: = inet_addr (myargv[i]+1);
312: }
313: else
314: {
315: hostentry = gethostbyname (myargv[i]);
316: if (!hostentry)
317: I_Error ("gethostbyname: couldn't find %s", myargv[i]);
318: sendaddress[doomcom->numnodes].sin_addr.s_addr
319: = *(int *)hostentry->h_addr_list[0];
320: }
321: doomcom->numnodes++;
322: }
323:
324: doomcom->id = DOOMCOM_ID;
325: doomcom->numplayers = doomcom->numnodes;
326:
327: // build message to receive
328: insocket = UDPsocket ();
329: BindToLocalPort (insocket,htons(DOOMPORT));
330: ioctl (insocket, FIONBIO, &trueval);
331:
332: sendsocket = UDPsocket ();
333: }
334:
335:
336: void I_NetCmd (void)
337: {
338: if (doomcom->command == CMD_SEND)
339: {
340: netsend ();
341: }
342: else if (doomcom->command == CMD_GET)
343: {
344: netget ();
345: }
346: else
347: I_Error ("Bad net cmd: %i\n",doomcom->command);
348: }
349:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.