home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2004 August / GSSH0804.iso / Geschicklichkeit / RocksnDiamonds / rocksndiamonds.exe / rocksndiamonds-3.1.0 / src / netserv.c < prev    next >
C/C++ Source or Header  |  2004-04-27  |  18KB  |  807 lines

  1. /***********************************************************
  2. * Rocks'n'Diamonds -- McDuffin Strikes Back!               *
  3. *----------------------------------------------------------*
  4. * (c) 1995-2002 Artsoft Entertainment                      *
  5. *               Holger Schemel                             *
  6. *               Detmolder Strasse 189                      *
  7. *               33604 Bielefeld                            *
  8. *               Germany                                    *
  9. *               e-mail: info@artsoft.org                   *
  10. *----------------------------------------------------------*
  11. * netserv.c                                                *
  12. ***********************************************************/
  13.  
  14. #include "libgame/platform.h"
  15.  
  16. #if defined(NETWORK_AVALIABLE)
  17.  
  18. #include <fcntl.h>
  19. #include <sys/time.h>
  20. #include <signal.h>
  21. #include <errno.h>
  22.  
  23. #if defined(TARGET_SDL)
  24. #include "main.h"
  25. #else
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <netinet/tcp.h>
  29. #include <arpa/inet.h>
  30. #include <netdb.h>
  31. #include <sys/select.h>            /* apparently needed for OS/2 port */
  32. #endif
  33.  
  34. #include "libgame/libgame.h"
  35.  
  36. #include "netserv.h"
  37.  
  38. static int clients = 0;
  39. static int onceonly = 0;
  40.  
  41. struct NetworkServerPlayerInfo
  42. {
  43. #if defined(TARGET_SDL)
  44.   TCPsocket fd;
  45. #else
  46.   int fd;
  47. #endif
  48.  
  49.   char player_name[16];
  50.   unsigned char number;
  51.   struct NetworkServerPlayerInfo *next;
  52.   char active;
  53.   char introduced;
  54.   unsigned char readbuffer[MAX_BUFFER_SIZE];
  55.   unsigned char writbuffer[MAX_BUFFER_SIZE];
  56.   int nread, nwrite;
  57.   byte action;
  58.   boolean action_received;
  59. };
  60.  
  61. static struct NetworkServerPlayerInfo *first_player = NULL;
  62.  
  63. #define NEXT(player) ((player)->next ? (player)->next : first_player)
  64.  
  65. #if defined(TARGET_SDL)
  66. /* TODO: peer address */
  67. static TCPsocket lfd;        /* listening socket */
  68. static SDLNet_SocketSet fds;    /* socket set */
  69. #else
  70. static struct sockaddr_in saddr;
  71. static int lfd;            /* listening socket */
  72. static fd_set fds;        /* socket set */
  73. static int tcp = -1;
  74. #endif
  75.  
  76. static unsigned char realbuffer[512], *buffer = realbuffer + 4;
  77.  
  78. static int interrupt;
  79.  
  80. static unsigned long ServerFrameCounter = 0;
  81.  
  82. static void addtobuffer(struct NetworkServerPlayerInfo *player,
  83.             unsigned char *b, int len)
  84. {
  85.   if (player->nwrite + len >= MAX_BUFFER_SIZE)
  86.     Error(ERR_EXIT_NETWORK_SERVER,
  87.       "internal error: network send buffer overflow");
  88.  
  89.   memcpy(player->writbuffer + player->nwrite, b, len);
  90.   player->nwrite += len;
  91. }
  92.  
  93. static void flushuser(struct NetworkServerPlayerInfo *player)
  94. {
  95.   if (player->nwrite)
  96.   {
  97. #if defined(TARGET_SDL)
  98.     SDLNet_TCP_Send(player->fd, player->writbuffer, player->nwrite);
  99. #else
  100.     write(player->fd, player->writbuffer, player->nwrite);
  101. #endif
  102.     player->nwrite = 0;
  103.   }
  104. }
  105.  
  106. static void broadcast(struct NetworkServerPlayerInfo *except,
  107.               int len, int activeonly)
  108. {
  109.   struct NetworkServerPlayerInfo *player;
  110.  
  111.   realbuffer[0] = realbuffer[1] = realbuffer[2] = 0;
  112.   realbuffer[3] = (unsigned char)len;
  113.   for (player = first_player; player; player = player->next)
  114.     if (player != except && player->introduced &&
  115.     (player->active || !activeonly))
  116.       addtobuffer(player, realbuffer, 4 + len);
  117. }
  118.  
  119. static void sendtoone(struct NetworkServerPlayerInfo *to, int len)
  120. {
  121.   realbuffer[0] = realbuffer[1] = realbuffer[2] = 0;
  122.   realbuffer[3] = (unsigned char)len;
  123.   addtobuffer(to, realbuffer, 4 + len);
  124. }
  125.  
  126. static void RemovePlayer(struct NetworkServerPlayerInfo *player)
  127. {
  128.   struct NetworkServerPlayerInfo *v;
  129.   
  130.   if (options.verbose)
  131.     Error(ERR_NETWORK_SERVER, "dropping client %d (%s)",
  132.       player->number, player->player_name);
  133.  
  134.   if (player == first_player)
  135.     first_player = player->next;
  136.   else
  137.   {
  138.     for (v = first_player; v; v = v->next)
  139.     {
  140.       if (v->next && v->next == player)
  141.       {
  142.     v->next = player->next;
  143.     break;
  144.       }
  145.     }
  146.   }
  147.  
  148. #if defined(TARGET_SDL)
  149.   SDLNet_TCP_DelSocket(fds, player->fd);
  150.   SDLNet_TCP_Close(player->fd);
  151. #else
  152.   close(player->fd);
  153. #endif
  154.  
  155.   if (player->introduced)
  156.   {
  157.     buffer[0] = player->number;
  158.     buffer[1] = OP_PLAYER_DISCONNECTED;
  159.     broadcast(player, 2, 0);
  160.   }
  161.  
  162.   free(player);
  163.   clients--;
  164.  
  165.   if (onceonly && clients == 0)
  166.   {
  167.     if (options.verbose)
  168.     {
  169.       Error(ERR_NETWORK_SERVER, "no clients left");
  170.       Error(ERR_NETWORK_SERVER, "aborting");
  171.     }
  172.     exit(0);
  173.   }
  174. }
  175.  
  176. #if defined(TARGET_SDL)
  177. static void AddPlayer(TCPsocket fd)
  178. #else
  179. static void AddPlayer(int fd)
  180. #endif
  181. {
  182.   struct NetworkServerPlayerInfo *player, *v;
  183.   unsigned char nxn;
  184.   boolean again = TRUE;
  185.  
  186.   player = checked_malloc(sizeof (struct NetworkServerPlayerInfo));
  187.  
  188.   player->fd = fd;
  189.   player->player_name[0] = 0;
  190.   player->next = first_player;
  191.   player->active = 0;
  192.   player->nread = 0;
  193.   player->nwrite = 0;
  194.   player->introduced = 0;
  195.   player->action = 0;
  196.   player->action_received = FALSE;
  197.  
  198. #if defined(TARGET_SDL)
  199.   SDLNet_TCP_AddSocket(fds, fd);
  200. #endif
  201.  
  202.   first_player = player;
  203.  
  204.   nxn = 1;
  205.  
  206. #if 1
  207.   while (again)
  208.   {
  209.     again = FALSE;
  210.     v = player->next;
  211.  
  212.     while (v)
  213.     {
  214.       if (v->number == nxn)
  215.       {
  216.     nxn++;
  217.  
  218.     again = TRUE;
  219.     break;
  220.       }
  221.       v = v->next;
  222.     }
  223.   }
  224. #else
  225.  again:
  226.   v = player->next;
  227.   while (v)
  228.   {
  229.     if (v->number == nxn)
  230.     {
  231.       nxn++;
  232.       goto again;
  233.     }
  234.     v = v->next;
  235.   }
  236. #endif
  237.  
  238.   player->number = nxn;
  239. #if !defined(TARGET_SDL)
  240.   if (options.verbose)
  241.     Error(ERR_NETWORK_SERVER, "client %d connecting from %s",
  242.       nxn, inet_ntoa(saddr.sin_addr));
  243. #endif
  244.   clients++;
  245.  
  246.   buffer[0] = 0;
  247.   buffer[1] = OP_YOUR_NUMBER;
  248.   buffer[2] = player->number;
  249.   sendtoone(player, 3);
  250. }
  251.  
  252. static void Handle_OP_PROTOCOL_VERSION(struct NetworkServerPlayerInfo *player,
  253.                        unsigned int len)
  254. {
  255.   if (len != 5 ||
  256.       buffer[2] != PROTOCOL_VERSION_1 ||
  257.       buffer[3] != PROTOCOL_VERSION_2)
  258.   {
  259.     if (options.verbose)
  260.       Error(ERR_NETWORK_SERVER,
  261.         "client %d (%s) has wrong protocol version %d.%d.%d",
  262.         player->number, player->player_name, buffer[2], buffer[3], buffer[4]);
  263.  
  264.     buffer[0] = 0;
  265.     buffer[1] = OP_BAD_PROTOCOL_VERSION;
  266.     buffer[2] = PROTOCOL_VERSION_1;
  267.     buffer[3] = PROTOCOL_VERSION_2;
  268.     buffer[4] = PROTOCOL_VERSION_3;
  269.     sendtoone(player, 5);
  270.     flushuser(player);
  271.  
  272.     RemovePlayer(player);
  273.     interrupt = 1;
  274.   }
  275.   else
  276.   {
  277.     if (options.verbose)
  278.       Error(ERR_NETWORK_SERVER,
  279.         "client %d (%s) uses protocol version %d.%d.%d",
  280.         player->number, player->player_name, buffer[2], buffer[3], buffer[4]);
  281.   }
  282. }
  283.  
  284. static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player)
  285. {
  286.   struct NetworkServerPlayerInfo *v;
  287.   int client_nr = player->number;
  288.   int nr_wanted = buffer[2];
  289.   int nr_is_free = 1;
  290.  
  291.   if (options.verbose)
  292.       Error(ERR_NETWORK_SERVER, "client %d (%s) wants to switch to # %d",
  293.         player->number, player->player_name, nr_wanted);
  294.  
  295.   for (v = first_player; v; v = v->next)
  296.   {
  297.     if (v->number == nr_wanted)
  298.     {
  299.       nr_is_free = 0;
  300.       break;
  301.     }
  302.   }
  303.  
  304.   if (options.verbose)
  305.   {
  306.     if (nr_is_free)
  307.       Error(ERR_NETWORK_SERVER, "client %d (%s) switches to # %d",
  308.         player->number, player->player_name, nr_wanted);
  309.     else if (player->number == nr_wanted)
  310.       Error(ERR_NETWORK_SERVER, "client %d (%s) still has # %d",
  311.         player->number, player->player_name, nr_wanted);
  312.     else
  313.       Error(ERR_NETWORK_SERVER,
  314.         "client %d (%s) cannot switch (client %d still exists)",
  315.         player->number, player->player_name, nr_wanted);
  316.   }
  317.  
  318.   if (nr_is_free)
  319.     player->number = nr_wanted;
  320.  
  321.   buffer[0] = client_nr;
  322.   buffer[1] = OP_NUMBER_WANTED;
  323.   buffer[2] = nr_wanted;
  324.   buffer[3] = player->number;
  325.  
  326.   /*
  327.   sendtoone(player, 4);
  328.   */
  329.  
  330.   broadcast(NULL, 4, 0);
  331. }
  332.  
  333. static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player,
  334.                   unsigned int len)
  335. {
  336.   struct NetworkServerPlayerInfo *v;
  337.   int i;
  338.  
  339.   if (len>16)
  340.     len=16;
  341.   memcpy(player->player_name, &buffer[2], len-2);
  342.   player->player_name[len-2] = 0;
  343.   for (i = 0; i < len - 2; i++)
  344.   {
  345.     if (player->player_name[i] < ' ' || 
  346.     ((unsigned char)(player->player_name[i]) > 0x7e &&
  347.      (unsigned char)(player->player_name[i]) <= 0xa0))
  348.     {
  349.       player->player_name[i] = 0;
  350.       break;
  351.     }
  352.   }
  353.  
  354.   if (!player->introduced)
  355.   {
  356.     buffer[0] = player->number;
  357.     buffer[1] = OP_PLAYER_CONNECTED;
  358.     broadcast(player, 2, 0);
  359.   }
  360.           
  361.   if (options.verbose)
  362.     Error(ERR_NETWORK_SERVER, "client %d calls itself \"%s\"",
  363.       player->number, player->player_name);
  364.   buffer[1] = OP_PLAYER_NAME;
  365.   broadcast(player, len, 0);
  366.  
  367.   if (!player->introduced)
  368.   {
  369.     for (v = first_player; v; v = v->next)
  370.     {
  371.       if (v != player && v->introduced)
  372.       {
  373.     buffer[0] = v->number;
  374.     buffer[1] = OP_PLAYER_CONNECTED;
  375.     sendtoone(player, 2);
  376.     buffer[1] = OP_PLAYER_NAME;
  377.     memcpy(&buffer[2], v->player_name, 14);
  378.     sendtoone(player, 2+strlen(v->player_name));
  379.       }
  380.     }
  381.   }
  382.  
  383.   player->introduced = 1;
  384. }
  385.  
  386. static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player)
  387. {
  388.   struct NetworkServerPlayerInfo *v, *w;
  389.  
  390.   if (options.verbose)
  391.     Error(ERR_NETWORK_SERVER,
  392.       "client %d (%s) starts game [level %d from levedir %d (%s)]",
  393.       player->number, player->player_name,
  394.       (buffer[2] << 8) + buffer[3],
  395.       (buffer[4] << 8) + buffer[5],
  396.       &buffer[6]);
  397.  
  398.   for (w = first_player; w; w = w->next)
  399.     if (w->introduced)
  400.       w->active = 1;
  401.  
  402.   /* reset frame counter */
  403.   ServerFrameCounter = 0;
  404.  
  405.   /* reset player actions */
  406.   for (v = first_player; v; v = v->next)
  407.   {
  408.     v->action = 0;
  409.     v->action_received = FALSE;
  410.   }
  411.  
  412.   broadcast(NULL, 10 + strlen((char *)&buffer[10])+1, 0);
  413. }
  414.  
  415. static void Handle_OP_PAUSE_PLAYING(struct NetworkServerPlayerInfo *player)
  416. {
  417.   if (options.verbose)
  418.     Error(ERR_NETWORK_SERVER, "client %d (%s) pauses game",
  419.       player->number, player->player_name);
  420.   broadcast(NULL, 2, 0);
  421. }
  422.  
  423. static void Handle_OP_CONTINUE_PLAYING(struct NetworkServerPlayerInfo *player)
  424. {
  425.   if (options.verbose)
  426.     Error(ERR_NETWORK_SERVER, "client %d (%s) continues game",
  427.       player->number, player->player_name);
  428.   broadcast(NULL, 2, 0);
  429. }
  430.  
  431. static void Handle_OP_STOP_PLAYING(struct NetworkServerPlayerInfo *player)
  432. {
  433.   if (options.verbose)
  434.     Error(ERR_NETWORK_SERVER, "client %d (%s) stops game",
  435.       player->number, player->player_name);
  436.   broadcast(NULL, 2, 0);
  437. }
  438.  
  439. static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player)
  440. {
  441.   struct NetworkServerPlayerInfo *v;
  442.   int last_client_nr = 0;
  443.   int i;
  444.  
  445.   /* store player action */
  446.   for (v = first_player; v; v = v->next)
  447.   {
  448.     if (v->number == player->number)
  449.     {
  450.       v->action = buffer[2];
  451.       v->action_received = TRUE;
  452.     }
  453.   }
  454.  
  455.   /* check if server received action from each player */
  456.   for (v = first_player; v; v = v->next)
  457.   {
  458.     if (!v->action_received)
  459.       return;
  460.  
  461.     if (v->number > last_client_nr)
  462.       last_client_nr = v->number;
  463.   }
  464.  
  465.   /* initialize all player actions to zero */
  466.   for (i = 0; i < last_client_nr; i++)
  467.     buffer[6 + i] = 0;
  468.  
  469.   /* broadcast actions of all players to all players */
  470.   for (v = first_player; v; v = v->next)
  471.   {
  472.     buffer[6 + v->number-1] = v->action;
  473.     v->action = 0;
  474.     v->action_received = FALSE;
  475.   }
  476.  
  477.   buffer[2] = (unsigned char)((ServerFrameCounter >> 24) & 0xff);
  478.   buffer[3] = (unsigned char)((ServerFrameCounter >> 16) & 0xff);
  479.   buffer[4] = (unsigned char)((ServerFrameCounter >>  8) & 0xff);
  480.   buffer[5] = (unsigned char)((ServerFrameCounter >>  0) & 0xff);
  481.  
  482.   broadcast(NULL, 6 + last_client_nr, 0);
  483.  
  484.   ServerFrameCounter++;
  485. }
  486.  
  487. #if defined(TARGET_SDL)
  488. /* the following is not used for a standalone server;
  489.    the pointer points to an integer containing the port-number */
  490. int NetworkServerThread(void *ptr)
  491. {
  492.   NetworkServer(*((int *) ptr), 0);
  493.  
  494.   /* should never be reached */
  495.   return 0;
  496. }
  497. #endif
  498.  
  499. void NetworkServer(int port, int serveronly)
  500. {
  501.   int sl;
  502.   struct NetworkServerPlayerInfo *player;
  503.   int r; 
  504.   unsigned int len;
  505. #if defined(TARGET_SDL)
  506.   IPaddress ip;
  507. #else
  508.   int i, on;
  509.   int is_daemon = 0;
  510.   struct protoent *tcpproto;
  511.   struct timeval tv;
  512.   int mfd;
  513. #endif
  514.  
  515. #if defined(PLATFORM_UNIX) && !defined(PLATFORM_NEXT)
  516.   struct sigaction sact;
  517. #endif
  518.  
  519.   if (port == 0)
  520.     port = DEFAULT_SERVER_PORT;
  521.  
  522.   if (!serveronly)
  523.     onceonly = 1;
  524.  
  525. #if !defined(TARGET_SDL)
  526.   if ((tcpproto = getprotobyname("tcp")) != NULL)
  527.     tcp = tcpproto->p_proto;
  528. #endif
  529.  
  530. #if defined(PLATFORM_UNIX)
  531. #if defined(PLATFORM_NEXT)
  532.   signal(SIGPIPE, SIG_IGN);
  533. #else
  534.   sact.sa_handler = SIG_IGN;
  535.   sigemptyset(&sact.sa_mask);
  536.   sact.sa_flags = 0;
  537.   sigaction(SIGPIPE, &sact, NULL);
  538. #endif
  539. #endif
  540.  
  541. #if defined(TARGET_SDL)
  542.  
  543.   /* assume that SDL is already initialized */
  544. #if 0
  545.   if (SDLNet_Init() == -1)
  546.     Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_Init() failed");
  547.   atexit(SDLNet_Quit);
  548. #endif
  549.  
  550.   if (SDLNet_ResolveHost(&ip, NULL, port) == -1)
  551.     Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed");
  552.  
  553.   lfd = SDLNet_TCP_Open(&ip);
  554.   if (!lfd)
  555.     Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed");
  556.  
  557.   fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1);
  558.   SDLNet_TCP_AddSocket(fds, lfd);
  559.  
  560. #else
  561.  
  562.   if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
  563.     Error(ERR_EXIT_NETWORK_SERVER, "socket() failed");
  564.  
  565.   saddr.sin_family = AF_INET;
  566.   saddr.sin_addr.s_addr = htonl(INADDR_ANY);
  567.   saddr.sin_port = htons(port);
  568.  
  569.   on = 1;
  570.  
  571.   setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(int));
  572.   if (bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
  573.     Error(ERR_EXIT_NETWORK_SERVER, "bind() failed");
  574.  
  575.   listen(lfd, 5);
  576. #endif
  577.  
  578. #if !defined(TARGET_SDL)
  579.   if (is_daemon)
  580.   {
  581.     /* become a daemon, breaking all ties with the controlling terminal */
  582.     options.verbose = FALSE;
  583.     for (i = 0; i < 255; i++)
  584.     {
  585.       if (i != lfd)
  586.     close(i);
  587.     }
  588.  
  589.     if (fork())
  590.       exit(0);
  591.     setsid();
  592.     if (fork())
  593.       exit(0);
  594.     chdir("/");
  595.  
  596.     /* open a fake stdin, stdout, stderr, just in case */
  597.     open("/dev/null", O_RDONLY);
  598.     open("/dev/null", O_WRONLY);
  599.     open("/dev/null", O_WRONLY);
  600.   }
  601. #endif
  602.  
  603.   if (options.verbose)
  604.   {
  605.     Error(ERR_NETWORK_SERVER, "started up, listening on port %d", port);
  606.     Error(ERR_NETWORK_SERVER, "using protocol version %d.%d.%d",
  607.       PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, PROTOCOL_VERSION_3);
  608.   }
  609.  
  610.   while (1)
  611.   {
  612.     interrupt = 0;
  613.  
  614.     for (player = first_player; player; player = player->next)
  615.       flushuser(player);
  616.  
  617. #if defined(TARGET_SDL)
  618.     if ((sl = SDLNet_CheckSockets(fds, 500000)) < 1)
  619.     {
  620.       Error(ERR_NETWORK_SERVER, SDLNet_GetError());
  621.       perror("SDLNet_CheckSockets");
  622.     }
  623.  
  624. #else
  625.  
  626.     FD_ZERO(&fds);
  627.     mfd = lfd;
  628.     player = first_player;
  629.     while (player)
  630.     {
  631.       FD_SET(player->fd, &fds);
  632.       if (player->fd > mfd)
  633.     mfd = player->fd;
  634.       player = player->next;
  635.     }
  636.     FD_SET(lfd, &fds);
  637.     tv.tv_sec = 0;
  638.     tv.tv_usec = 500000;
  639.     if ((sl = select(mfd + 1, &fds, NULL, NULL, &tv)) < 0)
  640.     {
  641.       if (errno != EINTR)
  642.     Error(ERR_EXIT_NETWORK_SERVER, "select() failed");
  643.       else
  644.     continue;
  645.     }
  646. #endif
  647.  
  648.     if (sl < 0)
  649.       continue;
  650.     
  651.     if (sl == 0)
  652.       continue;
  653.  
  654.     /* accept incoming connections */
  655. #if defined(TARGET_SDL)
  656.     if (SDLNet_SocketReady(lfd))
  657.     {
  658.       TCPsocket newsock;
  659.  
  660.       newsock = SDLNet_TCP_Accept(lfd);
  661.  
  662.       if (newsock)
  663.     AddPlayer(newsock);
  664.     }
  665.  
  666. #else
  667.  
  668.     if (FD_ISSET(lfd, &fds))
  669.     {
  670.       int newfd, slen;
  671.  
  672.       slen = sizeof(saddr);
  673.       newfd = accept(lfd, (struct sockaddr *)&saddr, &slen);
  674.       if (newfd < 0)
  675.       {
  676.     if (errno != EINTR)
  677.       Error(ERR_EXIT_NETWORK_SERVER, "accept() failed");
  678.       }
  679.       else
  680.       {
  681.     if (tcp != -1)
  682.     {
  683.       on = 1;
  684.       setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int));
  685.     }
  686.     AddPlayer(newfd);
  687.       }
  688.       continue;
  689.     }
  690. #endif
  691.  
  692.     player = first_player;
  693.  
  694.     do
  695.     {
  696. #if defined(TARGET_SDL)
  697.       if (SDLNet_SocketReady(player->fd))
  698. #else
  699.       if (FD_ISSET(player->fd, &fds))
  700. #endif
  701.       {
  702. #if defined(TARGET_SDL)
  703.     /* read only 1 byte, because SDLNet blocks when we want more than is
  704.        in the buffer */
  705.     r = SDLNet_TCP_Recv(player->fd, player->readbuffer + player->nread, 1);
  706. #else
  707.     r = read(player->fd, player->readbuffer + player->nread,
  708.          MAX_BUFFER_SIZE - player->nread);
  709. #endif
  710.  
  711.     if (r <= 0)
  712.     {
  713.       if (options.verbose)
  714.         Error(ERR_NETWORK_SERVER, "EOF from client %d (%s)",
  715.           player->number, player->player_name);
  716.       RemovePlayer(player);
  717.       interrupt = 1;
  718.       break;
  719.     }
  720.     player->nread += r;
  721.     while (player->nread >= 4 && player->nread >= 4 + player->readbuffer[3])
  722.     {
  723.       len = player->readbuffer[3];
  724.       if (player->readbuffer[0] || player->readbuffer[1] || player->readbuffer[2])
  725.       {
  726.         if (options.verbose)
  727.           Error(ERR_NETWORK_SERVER, "crap from client %d (%s)",
  728.             player->number, player->player_name);
  729.         RemovePlayer(player);
  730.         interrupt = 1;
  731.         break;
  732.       }
  733.       memcpy(buffer, &player->readbuffer[4], len);
  734.       player->nread -= 4 + len;
  735.       memmove(player->readbuffer, player->readbuffer + 4 + len, player->nread);
  736.  
  737.       buffer[0] = player->number;
  738.       if (!player->introduced && buffer[1] != OP_PLAYER_NAME)
  739.       {
  740.         if (options.verbose)
  741.           Error(ERR_NETWORK_SERVER, "!(client %d)->introduced && buffer[1]==%d (expected OP_PLAYER_NAME)", buffer[0], buffer[1]);
  742.  
  743.         RemovePlayer(player);
  744.         interrupt = 1;
  745.         break;
  746.       }
  747.  
  748.       switch(buffer[1])
  749.       {
  750.         case OP_PLAYER_NAME:
  751.           Handle_OP_PLAYER_NAME(player, len);
  752.           break;
  753.  
  754.         case OP_PROTOCOL_VERSION:
  755.           Handle_OP_PROTOCOL_VERSION(player, len);
  756.           break;
  757.  
  758.         case OP_NUMBER_WANTED:
  759.           Handle_OP_NUMBER_WANTED(player);
  760.           break;
  761.  
  762.         case OP_START_PLAYING:
  763.           Handle_OP_START_PLAYING(player);
  764.           break;
  765.  
  766.         case OP_PAUSE_PLAYING:
  767.           Handle_OP_PAUSE_PLAYING(player);
  768.           break;
  769.  
  770.         case OP_CONTINUE_PLAYING:
  771.           Handle_OP_CONTINUE_PLAYING(player);
  772.           break;
  773.  
  774.         case OP_STOP_PLAYING:
  775.           Handle_OP_STOP_PLAYING(player);
  776.           break;
  777.  
  778.         case OP_MOVE_PLAYER:
  779.           Handle_OP_MOVE_PLAYER(player);
  780.           break;
  781.  
  782.         case OP_BROADCAST_MESSAGE:
  783.           buffer[len] = '\0';
  784.           if (options.verbose)
  785.         Error(ERR_NETWORK_SERVER, "client %d (%s) sends message: %s",
  786.               player->number, player->player_name, &buffer[2]);
  787.           broadcast(player, len, 0);
  788.           break;
  789.         
  790.         default:
  791.           if (options.verbose)
  792.         Error(ERR_NETWORK_SERVER,
  793.               "unknown opcode %d from client %d (%s)",
  794.               buffer[0], player->number, player->player_name);
  795.       }
  796.     }
  797.       }
  798.  
  799.       if (player && !interrupt)
  800.     player = player->next;
  801.     }
  802.     while (player && !interrupt);
  803.   }
  804. }
  805.  
  806. #endif /* NETWORK_AVALIABLE */
  807.