i_net.c 7.8 KB

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