i_net.c
上传用户:xuyinpeng
上传日期:2021-05-12
资源大小:455k
文件大小:9k
源码类别:

射击游戏

开发平台:

Visual C++

  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.   
  53. #define htonl(x) ntohl(x)
  54. #define htons(x) ntohs(x)
  55. void NetSend (void);
  56. boolean NetListen (void);
  57. char MsgText[2048];
  58. void WriteDebug(char *);
  59. //
  60. // NETWORKING
  61. //
  62. // FIXME
  63. #define IPPORT_USERRESERVED 26000
  64. int DOOMPORT = (IPPORT_USERRESERVED +0x1d );
  65. int sendsocket;
  66. int insocket;
  67. struct sockaddr_in sendaddress[MAXNETNODES];
  68. void (*netget) (void);
  69. void (*netsend) (void);
  70. //
  71. // UDPsocket
  72. //
  73. int UDPsocket (void)
  74.    {
  75.     int s;
  76.     // allocate a socket
  77.     s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  78.     if (s < 0)
  79.        {
  80.         sprintf(MsgText, "ERROR:Can't create socket:%08X %sn", errno, strerror(errno));
  81.         I_Error(MsgText);
  82.        }
  83.     return s;
  84.    }
  85. //
  86. // BindToLocalPort
  87. //
  88. void BindToLocalPort( int s, int port )
  89.    {
  90.     int v;
  91.     struct sockaddr_in address;
  92.     memset (&address, 0, sizeof(address));
  93.     address.sin_family = AF_INET;
  94.     address.sin_addr.s_addr = INADDR_ANY;
  95.     address.sin_port = port;
  96.     v = bind(s, (void *)&address, sizeof(address));
  97.     if (v == -1)
  98.         I_Error ("BindToPort: bind: %s", strerror(errno));
  99.    }
  100. //
  101. // PacketSend
  102. //
  103. void PacketSend (void)
  104. {
  105.     int c;
  106.     doomdata_t sw;
  107.     // byte swap
  108.     sw.checksum = htonl(netbuffer->checksum);
  109.     sw.player = netbuffer->player;
  110.     sw.retransmitfrom = netbuffer->retransmitfrom;
  111.     sw.starttic = netbuffer->starttic;
  112.     sw.numtics = netbuffer->numtics;
  113.     for (c=0 ; c< netbuffer->numtics ; c++)
  114.     {
  115. sw.cmds[c].forwardmove = netbuffer->cmds[c].forwardmove;
  116. sw.cmds[c].sidemove = netbuffer->cmds[c].sidemove;
  117. sw.cmds[c].angleturn = htons(netbuffer->cmds[c].angleturn);
  118. sw.cmds[c].consistancy = htons(netbuffer->cmds[c].consistancy);
  119. sw.cmds[c].chatchar = netbuffer->cmds[c].chatchar;
  120. sw.cmds[c].buttons = netbuffer->cmds[c].buttons;
  121.     }
  122.     //printf ("sending %in",gametic);
  123.     c = sendto (sendsocket , (const char far *)&sw, doomcom->datalength
  124. ,0,(void *)&sendaddress[doomcom->remotenode]
  125. ,sizeof(sendaddress[doomcom->remotenode]));
  126.     // if (c == -1)
  127.     // I_Error ("SendPacket error: %s",strerror(errno));
  128. }
  129. //
  130. // PacketGet
  131. //
  132. void PacketGet (void)
  133. {
  134.     int i;
  135.     int c;
  136.     struct sockaddr_in fromaddress;
  137.     int fromlen;
  138.     doomdata_t sw;
  139.     fromlen = sizeof(fromaddress);
  140.     c = recvfrom (insocket, (char far *)&sw, sizeof(sw),0,(struct sockaddr *)&fromaddress, &fromlen );
  141.     if (c == SOCKET_ERROR )
  142.        {
  143.         c = WSAGetLastError();
  144.     if (c != WSAEWOULDBLOCK)
  145.         I_Error ("GetPacket: Network error.");
  146.     doomcom->remotenode = -1; // no packet
  147.         return;
  148.        }
  149.     {
  150. static int first=1;
  151. if (first)
  152.        {
  153.     sprintf(MsgText,"len=%d:p=[0x%x 0x%x] n", c, *(int*)&sw, *((int*)&sw+1));
  154.         WriteDebug(MsgText);
  155.        }
  156. first = 0;
  157.     }
  158.     // find remote node number
  159.     for (i=0 ; i<doomcom->numnodes ; i++)
  160. if ( fromaddress.sin_addr.s_addr == sendaddress[i].sin_addr.s_addr )
  161.     break;
  162.     if (i == doomcom->numnodes)
  163.     {
  164. // packet is not from one of the players (new game broadcast)
  165. doomcom->remotenode = -1; // no packet
  166. return;
  167.     }
  168.     doomcom->remotenode = i; // good packet from a game player
  169.     doomcom->datalength = c;
  170.     // byte swap
  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.     for (c=0 ; c< netbuffer->numtics ; c++)
  177.     {
  178. netbuffer->cmds[c].forwardmove = sw.cmds[c].forwardmove;
  179. netbuffer->cmds[c].sidemove = sw.cmds[c].sidemove;
  180. netbuffer->cmds[c].angleturn = ntohs(sw.cmds[c].angleturn);
  181. netbuffer->cmds[c].consistancy = ntohs(sw.cmds[c].consistancy);
  182. netbuffer->cmds[c].chatchar = sw.cmds[c].chatchar;
  183. netbuffer->cmds[c].buttons = sw.cmds[c].buttons;
  184.     }
  185. }
  186. int GetLocalAddress (void)
  187. {
  188.     char hostname[1024];
  189.     struct hostent* hostentry; // host information entry
  190.     int v;
  191.     // get local address
  192.     v = gethostname (hostname, sizeof(hostname));
  193.     if (v == -1)
  194. I_Error ("GetLocalAddress : gethostname: errno %d",errno);
  195.     hostentry = gethostbyname (hostname);
  196.     if (!hostentry)
  197. I_Error ("GetLocalAddress : gethostbyname: couldn't get local host");
  198.     return *(int *)hostentry->h_addr_list[0];
  199. }
  200. //
  201. // I_InitNetwork
  202. //
  203. void I_InitNetwork (void)
  204.    {
  205.     boolean trueval = true;
  206.     int i, err;
  207.     int p;
  208.     struct hostent* hostentry; // host information entry
  209.     WORD wVersionRequested;  
  210.     WSADATA wsaData; 
  211.     doomcom = malloc (sizeof (*doomcom) );
  212.     memset (doomcom, 0, sizeof(*doomcom) );
  213.     
  214.     // set up for network
  215.     i = M_CheckParm ("-dup");
  216.     if (i && i< myargc-1)
  217.        {
  218.     doomcom->ticdup = myargv[i+1][0]-'0';
  219.     if (doomcom->ticdup < 1)
  220.             doomcom->ticdup = 1;
  221.         if (doomcom->ticdup > 9)
  222.             doomcom->ticdup = 9;
  223.        }
  224.     else
  225.        doomcom-> ticdup = 1;
  226.     if (M_CheckParm ("-extratic"))
  227.        doomcom-> extratics = 1;
  228.     else
  229.        doomcom-> extratics = 0;
  230.     p = M_CheckParm ("-port");
  231.     if (p && p<myargc-1)
  232.        {
  233.         DOOMPORT = atoi (myargv[p+1]);
  234.         //printf ("using alternate port %in",DOOMPORT);
  235.         sprintf (MsgText, "using alternate port %in",DOOMPORT);
  236.         WriteDebug(MsgText);
  237.        }
  238.     
  239.     // parse network game options,
  240.     //  -net <consoleplayer> <host> <host> ...
  241.     i = M_CheckParm ("-net");
  242.     if (!i)
  243.        {
  244.         // single player game
  245.         netgame = false;
  246.         doomcom->id = DOOMCOM_ID;
  247.         doomcom->numplayers = doomcom->numnodes = 1;
  248.         doomcom->deathmatch = false;
  249.         doomcom->consoleplayer = 0;
  250.         return;
  251.        }
  252.     wVersionRequested = MAKEWORD(2,2); 
  253.     err = WSAStartup(wVersionRequested, &wsaData); 
  254.  
  255.     netsend = PacketSend;
  256.     netget = PacketGet;
  257.     netgame = true;
  258.     // parse player number and host list
  259.     doomcom->consoleplayer = myargv[i+1][0]-'1';
  260.     sprintf(MsgText, "console player number : %dn", doomcom->consoleplayer);
  261.     WriteDebug(MsgText);
  262.     doomcom->numnodes = 1; // this node for sure
  263.     i++;
  264.     while (++i < myargc && myargv[i][0] != '-')
  265.        {
  266.     sendaddress[doomcom->numnodes].sin_family = AF_INET;
  267.     sendaddress[doomcom->numnodes].sin_port = htons(DOOMPORT);
  268.     if (myargv[i][0] == '.')
  269.        {
  270.             sprintf(MsgText, "Node number %d address %sn", doomcom->numnodes, myargv[i]+1);
  271.             WriteDebug(MsgText);
  272.         sendaddress[doomcom->numnodes].sin_addr.s_addr = inet_addr(myargv[i]+1);
  273.        }
  274.         else
  275.            {
  276.             sprintf(MsgText, "Node number %d hostname %sn", doomcom->numnodes, myargv[i]);
  277.             WriteDebug(MsgText);
  278.             hostentry = gethostbyname(myargv[i]);
  279.             if (!hostentry)
  280.                 I_Error ("gethostbyname: couldn't find %s", myargv[i]);
  281.             sendaddress[doomcom->numnodes].sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
  282.            }
  283.         doomcom->numnodes++;
  284.        }
  285.     sprintf(MsgText, "Total number of players : %dn", (doomcom->numnodes-1));
  286.     WriteDebug(MsgText);
  287.     doomcom->id = DOOMCOM_ID;
  288.     doomcom->numplayers = doomcom->numnodes;
  289.     
  290. // build message to receive
  291.     insocket = UDPsocket();
  292.     BindToLocalPort(insocket,htons(DOOMPORT));
  293.     ioctlsocket(insocket, FIONBIO, &trueval);
  294.     sendsocket = UDPsocket();
  295.    }
  296. void I_NetCmd (void)
  297. {
  298.     if (doomcom->command == CMD_SEND)
  299.     {
  300. netsend ();
  301.     }
  302.     else if (doomcom->command == CMD_GET)
  303.     {
  304. netget ();
  305.     }
  306.     else
  307. I_Error ("Bad net cmd: %in",doomcom->command);
  308. }