home *** CD-ROM | disk | FTP | other *** search
/ Freelog Special Issue 2 / Freelog_HS_3_Setp_Oct_Nov_2000_CD2.mdx / Arcade / Orbit / src / server.c < prev    next >
C/C++ Source or Header  |  1999-09-27  |  22KB  |  1,138 lines

  1. /*
  2.  
  3. ORBIT, a freeware space combat simulator
  4. Copyright (C) 1999  Steve Belczyk <steve1@genesis.nred.ma.us>
  5.  
  6. This program is free software; you can redistribute it and/or
  7. modify it under the terms of the GNU General Public License
  8. as published by the Free Software Foundation; either version 2
  9. of the License, or (at your option) any later version.
  10.  
  11. This program is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  19.  
  20. */
  21.  
  22. #include "orbit.h"
  23.  
  24. #ifndef WIN32
  25. #include <sys/socket.h>
  26. #include <unistd.h>
  27. #include <netinet/in.h>
  28. #include <netdb.h>
  29. #include <arpa/inet.h>
  30. #include <netinet/tcp.h>
  31. #endif
  32.  
  33. #include <limits.h>
  34. #include <fcntl.h>
  35. #include <errno.h>
  36. #include <stdarg.h>
  37.  
  38. /*
  39.  *  All sorts of stuff the server does
  40.  */
  41.  
  42. DoServer()
  43. /*
  44.  *  I am an ORBIT server
  45.  */
  46. {
  47.     int c;
  48.  
  49.     /* Look for any new clients */
  50.     CheckForClient();
  51.  
  52.     /* Loop through clients */
  53.     for (c=0; c<NCLIENTS; c++)
  54.     {
  55.         if (client[c].active) DoThisClient (c);
  56.     }
  57. }
  58.  
  59. DoThisClient (c)
  60. int c;
  61. /*
  62.  *  Server handles client c
  63.  */
  64. {
  65.     int i;
  66.  
  67.     /* Don't bother if this client is not active */
  68.     if (!client[c].active) return;
  69.  
  70.     /* Don't bother if this client is us */
  71.     if (client[c].is_me) return;
  72.  
  73.     /* Bump times */
  74.     client[c].timer.idle += deltaT;
  75.     client[c].timer.ping += deltaT;
  76.     for (i=0; i<NCLIENTS; i++) client[c].timer.posn[i] += deltaT;
  77.     client[c].timer.rollcall += deltaT;
  78.  
  79.     /* If client has been idle too long, goodbye */
  80.     if (client[c].timer.idle > MAXCLIENTIDLE)
  81.     {
  82.         Cprint ("Dropping idle client");
  83.         Log ("DoThisClient: Dropping idle client %d", c);
  84.         DropClient (c);
  85.         return;
  86.     }
  87.  
  88.     /* See if this client has anything to say to us */
  89.     ReadFromClient (c);
  90.  
  91.     /* Send anything we have to send to this client */
  92.     SendToClient (c);
  93.  
  94. }
  95.  
  96. SendToClient (c)
  97. int c;
  98. /*
  99.  *  Send anything we have to send to this client
  100.  */
  101. {
  102.     int cc;
  103.  
  104.     if (!client[c].active) return;
  105.  
  106.     /* Time to send ping? */
  107.     if (client[c].timer.ping >= PINGINTERVAL)
  108.     {
  109.         client[c].timer.ping = 0.0;
  110.         SendASCIIPacket (client[c].socket,
  111.             "PING %lf\n", absT);
  112.     }
  113.  
  114.     /* Time to send position reports? */
  115.     for (cc=0; cc<NCLIENTS; cc++)
  116.     {
  117.         /* Not if it's us and we're dead */
  118.         if ( (cc == server.client) &&
  119.              ((state == STATE_DEAD1) || (state == STATE_DEAD2)) ) continue;
  120.  
  121.         if (client[cc].active && (cc != c))
  122.         {
  123.             if (client[c].timer.posn[cc] > client[c].posninterval)
  124.             {
  125.                 /* Report client cc's position to client c */
  126.                 SendPosition (c, cc);
  127.                 client[c].timer.posn[cc] = 0.0;
  128.             }
  129.         }
  130.     }
  131.  
  132.     /* Time to send roll call? */
  133.     if (client[c].timer.rollcall >= ROLLCALLINTERVAL) SendRollCall (c);
  134. /**
  135.     if (client[c].timer.posn >= client[c].posninterval)
  136.     {
  137.         client[c].timer.posn = 0.0;
  138.         SendPositions (c);
  139.     }
  140. **/
  141. }
  142.  
  143. ReadFromClient (c)
  144. int c;
  145. /*
  146.  *  See if this client has anything to say to us
  147.  */
  148. {
  149.     char buf[1024];
  150.     int r, e;
  151.  
  152.     /* Bail if not there */
  153.     if (!client[c].active) return;
  154.  
  155.     /* Try to read from this client */
  156.     r = recv (client[c].socket, buf, 1024, 0);
  157.  
  158.     /* If recv returns zero the other side has gone away */
  159.     if (r == 0)
  160.     {
  161.         Cprint ("Client %d went away", c);
  162.         Log ("ReadFromClient: Client %d went away", c);
  163.         DropClient (c);
  164.  
  165.         return;
  166.     }
  167.  
  168.     /* If we get an error it better be EWOULDBLOCK */
  169. #ifndef WIN32
  170.     if (r < 0)
  171.     {
  172.         if (errno == EWOULDBLOCK)
  173.         {
  174.             /* All is well */
  175.             return;
  176.         }
  177.         else
  178.         {
  179.             /* Uh oh */
  180.             Log ("ReadFromClient: recv error: %d", errno);
  181.             return;
  182.         }
  183.     }
  184. #else
  185.     if (r == SOCKET_ERROR)
  186.     {
  187.         e = WSAGetLastError();
  188.         if (e == WSAEWOULDBLOCK)
  189.         {
  190.             /* All is well */
  191.             return;
  192.         }
  193.         else
  194.         {
  195.             /* Uh oh */
  196.             Log ("ReadFromClient: recv error: %d", e);
  197.             return;
  198.         }
  199.     }
  200. #endif
  201.  
  202.     /* We really have data from the client! */
  203.     client[c].timer.idle = 0.0;
  204.  
  205.     /* Handle the data */
  206.     buf[r] = 0;
  207.     recv_bytes += r;
  208. /*
  209.     Log ("ReadFromClient: Client %d data:", c);
  210.     LogWrite (buf, r);
  211. */
  212.     /* Handle packet from Client */
  213.     ClientData (c, buf, r);
  214. }
  215.  
  216. ClientData (c, buf, n)
  217. int c, n;
  218. char *buf;
  219. /*
  220.  *  Separate incoming data into packets
  221.  */
  222. {
  223.     int i;
  224. #ifndef BINARYPACKETS
  225.     int ch, j;
  226. #endif
  227.  
  228. #ifdef BINARYPACKETS
  229.     for (i=0; i<n; i++) ClientByte (c, buf[i]);
  230. #else
  231.     j = client[c].ptr;
  232.  
  233.     for (i=0; i<n; i++)
  234.     {
  235.         ch = client[c].pkt[j] = buf[i];
  236.         j = (j + 1) % 1024;
  237.  
  238.         /* Got a packet? */
  239.         if (ch == 0)
  240.         {
  241.             ClientPacket (c, client[c].pkt);
  242.             j = 0;
  243.         }
  244.     }
  245.  
  246.     client[c].ptr = j;
  247. #endif
  248. }
  249.  
  250. ClientByte (c, b)
  251. int c;
  252. char b;
  253. /*
  254.  *  Process one byte from server
  255.  */
  256. {
  257.     switch (client[c].state)
  258.     {
  259.     case NETSTATE_MAGIC:
  260.         if (b == NET_MAGIC)
  261.         {
  262.             client[c].state = NETSTATE_SIZE;
  263.         }
  264.         break;
  265.  
  266.     case NETSTATE_SIZE:
  267.         client[c].remain = 0xff & b;
  268.         client[c].ptr = 0;
  269.         client[c].state = NETSTATE_PACKET;
  270.         if (client[c].remain == 0) client[c].state = NETSTATE_MAGIC;
  271.         break;
  272.  
  273.     case NETSTATE_PACKET:
  274.         client[c].pkt[client[c].ptr++] = b;
  275.         client[c].remain--;
  276.         if (client[c].remain == 0)
  277.         {
  278.             client[c].pkt[client[c].ptr] = 0;
  279.             ClientPacket (c, client[c].pkt);
  280.             client[c].state = NETSTATE_MAGIC;
  281.         }
  282.         break;
  283.  
  284.     default:
  285.         Log ("ClientByte: PANIC! No such state: %d", client[c].state);
  286.         break;
  287.     }
  288. }
  289.  
  290. CheckForClient()
  291. /*
  292.  *  Look for a new network client
  293.  */
  294. {
  295.     int c, e, i, len;
  296.     SOCKET a;
  297.     int one = 1;
  298.     struct sockaddr_in sin;
  299. #ifdef WIN32
  300.     unsigned long longone = 1;
  301. #endif
  302.  
  303.     len = sizeof (sin);
  304.  
  305.     /* Ask for any outstanding connections */
  306.     a = accept (server.listening_socket, (struct sockaddr *) &sin, &len);
  307.  
  308. #ifndef WIN32
  309.     if (a < 0)
  310.     {
  311.         /* If the accept failed, it better be because the socket
  312.            is non-blocking or something went wrong */
  313.         if (errno == EWOULDBLOCK)
  314.         {
  315.             /* No problem, just no new connection */
  316.             return;
  317.         }
  318.         else
  319.         {
  320.             /* Uh oh */
  321.             Log ("CheckForClient: accept() error: %d", errno);
  322.             return;
  323.         }
  324.     }
  325. #else
  326.     if (a == SOCKET_ERROR)
  327.     {
  328.         e = WSAGetLastError();
  329.         if (e == WSAEWOULDBLOCK)
  330.         {
  331.             /* All is well, no new client */
  332.             return;
  333.         }
  334.         else
  335.         {
  336.             /* Uh oh */
  337.             Log ("CheckForClient: accept() error: %d", e);
  338.             return;
  339.         }
  340.     }
  341. #endif
  342.     else
  343.     {
  344.         /* Got one! */
  345.         c = FindClient();
  346.         if (c < 0)
  347.         {
  348.             Cprint ("Too many clients!");
  349.             Log ("CheckForClient: Too many clients");
  350. #ifndef WIN32
  351.             close (a);
  352. #else
  353.             closesocket (a);
  354. #endif
  355.         }
  356.         else
  357.         {
  358.             /* Make this socket non-blocking too */
  359. #ifdef WIN32
  360.             ioctlsocket (a, FIONBIO, &longone);
  361. #else
  362.             fcntl (a, F_SETFL, O_NONBLOCK);
  363. #endif
  364.  
  365.             /* Save client IP address */
  366.             strcpy (client[c].ip, inet_ntoa(sin.sin_addr));
  367.  
  368.             Log ("CheckForClient: Client %d [%s] connected", c, client[c].ip);
  369.             Cprint ("Client %d [%s] connected", c, client[c].ip);
  370.  
  371.             /* Disable the Nagle algorithm */
  372.             setsockopt (a, IPPROTO_TCP, TCP_NODELAY, (char *) &one,
  373.                 sizeof(one));
  374.  
  375.             /* Set up new client */
  376.             client[c].active = 1;
  377.             client[c].socket = a;
  378.             client[c].is_me = 0;
  379.             client[c].ping = 0.0;
  380.             client[c].posninterval = POSNINTERVALMEDIUM;
  381.             client[c].frags = 0;
  382.  
  383.             client[c].target = InitClientTarget();
  384.  
  385.             client[c].timer.idle = 0.0;
  386.             client[c].timer.ping = PINGINTERVAL;
  387.             for (i=0; i<NCLIENTS; i++) client[c].timer.posn[i] = 0.0;
  388.             client[c].timer.rollcall = 0.0;
  389.  
  390.             client[c].pkt[0] = 0;
  391.             client[c].ptr = 0;
  392.  
  393.             /* Send welcome message to new client */
  394.             SendASCIIPacket (client[c].socket, "WELC %d\n", c);
  395.             SendASCIIPacket (client[c].socket,
  396.                 "MESG Welcome, client %d, to the ORBIT server.\n", c);
  397.  
  398.             /* Send current roll call */
  399.             SendRollCall (c);
  400.         }
  401.     }
  402. }
  403.  
  404. ClientPacket (c, pkt)
  405. int c;
  406. char *pkt;
  407. /*
  408.  *  Handle packet from this client
  409.  */
  410. {
  411.     char cmd[128];
  412.  
  413. /*    Log ("ClientPacket: %s", pkt);    */
  414.  
  415.     /* High bit of first byte means this is a binary packet */
  416.     if (0x80 & pkt[0])
  417.     {
  418.         ClientBinaryPacket (c, pkt);
  419.         return;
  420.     }
  421.  
  422.     /* Sanity check on packet */
  423.     if ( (strlen(pkt) == 0) ||
  424.          (pkt[0] == ' ') ||
  425.          (pkt[0] == '\r') ||
  426.          (pkt[0] == '\n') ||
  427.          (pkt[0] == '\t') )
  428.     {
  429.         Log ("ClientPacket: Insane packet: %s", pkt);
  430.         return;
  431.     }
  432.  
  433.     /* Extract command part */
  434.     sscanf (pkt, "%s", cmd);
  435.  
  436.     /* Dispatch */
  437.     if (!strcasecmp (cmd, "posn"))
  438.     {
  439.         ClientPosition (c, pkt, 0);
  440.         return;
  441.     }
  442.     else if (!strcasecmp (cmd, "posu"))
  443.     {
  444.         ClientPosition (c, pkt, 1);
  445.         return;
  446.     }
  447.     else if (!strcasecmp (cmd, "fire"))
  448.     {
  449.         ClientFire (c, pkt);
  450.         return;
  451.     }
  452.     else if (!strcasecmp (cmd, "ping"))
  453.     {
  454.         ClientPing (c, pkt);
  455.         return;
  456.     }
  457.     else if (!strcasecmp (cmd, "chat"))
  458.     {
  459.         ClientChat (c, pkt);
  460.         return;
  461.     }
  462.     else if (!strcasecmp (cmd, "name"))
  463.     {
  464.         ClientName (c, pkt);
  465.         return;
  466.     }
  467.     else if (!strcasecmp (cmd, "modl"))
  468.     {
  469.         ClientModel (c, pkt);
  470.         return;
  471.     }
  472.     else if (!strcasecmp (cmd, "vers"))
  473.     {
  474.         ClientVersion (c, pkt);
  475.         return;
  476.     }
  477.     else
  478.     {
  479.         Log ("ClientPacket: Unrecongized command: %s", cmd);
  480.         return;
  481.     }
  482. }
  483.  
  484. ClientBinaryPacket (c, pkt)
  485. int c;
  486. unsigned char *pkt;
  487. /*
  488.  *  Binary packet from client c
  489.  */
  490. {
  491.     /* Dispatch */
  492.     switch (pkt[0])
  493.     {
  494.     case PKT_POSN:
  495.         ClientBinaryPosition (c, &pkt[1], 0);
  496.         break;
  497.  
  498.     case PKT_POSU:
  499.         ClientBinaryPosition (c, &pkt[1], 1);
  500.         break;
  501.  
  502.     case PKT_PING:
  503.         ClientBinaryPing (c, &pkt[1]);
  504.         break;
  505.  
  506.     default:
  507.         Log ("ClientBinaryPacket: Unrecognized packet type: 0x%x", pkt[0]);
  508.         break;
  509.     }
  510. }
  511.  
  512. ClientPing (c, pkt)
  513. int c;
  514. char *pkt;
  515. /*
  516.  *  Handle ping packet from client
  517.  */
  518. {
  519.     double t;
  520.  
  521.     /* Extract time from packet */
  522.     if (1 == sscanf (pkt, "%*s %lf", &t))
  523.     {
  524.         /* Compute ping round-trip time in milliseconds */
  525.         client[c].ping = 1000.0 * (absT - t);
  526.  
  527.         /* Use ping time to determine how fast we send position
  528.            reports to this client */
  529.         if (client[c].ping <= PINGFAST)
  530.         {
  531.             client[c].posninterval = POSNINTERVALSMALL;
  532.         }
  533.         else if (client[c].ping <= PINGSLOW)
  534.         {
  535.             client[c].posninterval = POSNINTERVALMEDIUM;
  536.         }
  537.         else
  538.         {
  539.             client[c].posninterval = POSNINTERVALLARGE;
  540.         }
  541.     }
  542.     else
  543.     {
  544.         Log ("ClientPing: Malformed ping packet: %s", pkt);
  545.     }
  546. }
  547.  
  548. ClientBinaryPing (c, pkt)
  549. int c;
  550. char *pkt;
  551. /*
  552.  *  Handle binary ping packet from client
  553.  */
  554. {
  555.     double t;
  556.  
  557.     /* Extract time from packet */
  558.     DecodeBinaryPacket (pkt, "F", &t);
  559.  
  560.     /* Compute ping round-trip time in milliseconds */
  561.     client[c].ping = 1000.0 * (absT - t);
  562.  
  563.     /* Use ping time to determine how fast we send position
  564.        reports to this client */
  565.     if (client[c].ping <= PINGFAST)
  566.     {
  567.         client[c].posninterval = POSNINTERVALSMALL;
  568.     }
  569.     else if (client[c].ping <= PINGSLOW)
  570.     {
  571.         client[c].posninterval = POSNINTERVALMEDIUM;
  572.     }
  573.     else
  574.     {
  575.         client[c].posninterval = POSNINTERVALLARGE;
  576.     }
  577. }
  578.  
  579. ShowClients ()
  580. /*
  581.  *  Give list of clients
  582.  */
  583. {
  584.     int c;
  585.     char buf[4096], buf2[256];
  586.  
  587.     if (!am_server && !am_client) return;
  588.  
  589.     /* Init message string */
  590.     strcpy (buf, "Active clients:\\\\");
  591.  
  592.     /* Add info for each active client */
  593.     for (c=0; c<NCLIENTS; c++)
  594.     {
  595.         if (client[c].active)
  596.         {
  597.             if (am_server)
  598.             {
  599.                 if (c == server.client)
  600.                 {
  601.                     sprintf (buf2, "%d) %s, idle %.0lf, ping %.0lf, frags %d\\",
  602.                         c, target[client[c].target].name,
  603.                         client[c].timer.idle, client[c].ping,
  604.                         client[c].frags);
  605.                 }
  606.                 else
  607.                 {
  608.                     sprintf (buf2, "%d) %s [%s], idle %.0lf, ping %.0lf, frags %d\\",
  609.                         c, target[client[c].target].name,
  610.                         client[c].ip, client[c].timer.idle, client[c].ping,
  611.                         client[c].frags);
  612.                 }
  613.             }
  614.             else if (am_client)
  615.             {
  616.                 sprintf (buf2, "%d) %s, frags %d\\",
  617.                     c, target[client[c].target].name,
  618.                     client[c].frags);
  619.             }
  620.  
  621.             strcat (buf, buf2);
  622.         }
  623.     }
  624.  
  625.     /* Give message */
  626.     Mprint (buf);
  627. }
  628.  
  629. ClientName (c, pkt)
  630. int c;
  631. char *pkt;
  632. /*
  633.  *  Set client name
  634.  */
  635. {
  636.     int cc;
  637.  
  638.     if ( (pkt[4] == 0) || (pkt[5] == 0) ) return;
  639.  
  640.     strncpy (target[client[c].target].name, &pkt[5], 16);
  641.     target[client[c].target].name[16] = 0;
  642.  
  643.     /* Tell us */
  644.     Cprint ("%s is here", target[client[c].target].name);
  645.  
  646.     /* Tell everyone else */
  647.     for (cc=0; cc<NCLIENTS; cc++)
  648.     {
  649.         if (client[cc].active && (cc != server.client) && (c != cc) )
  650.         {
  651.             SendASCIIPacket (client[cc].socket, "HELO %d %s",
  652.                 c, target[client[c].target].name);
  653.         }
  654.     }
  655. }
  656.  
  657. ClientModel (c, pkt)
  658. int c;
  659. char *pkt;
  660. /*
  661.  *  Set client model
  662.  */
  663. {
  664.     char buf[128];
  665.     int m;
  666.  
  667.     Log ("ClientModel: %s", pkt);
  668.  
  669.     /* Parse out model name */
  670.     if (1 != sscanf (pkt, "%*s %s", buf))
  671.     {
  672.         Log ("ClientModel: Malformed MODL packet: %s", pkt);
  673.         return;
  674.     }
  675.  
  676.     /* Try to load model */
  677.     m = LoadModel (buf);
  678.  
  679.     /* Success? */
  680.     if (m != (-1))
  681.     {
  682.         target[client[c].target].model = m;
  683.         target[client[c].target].list = model[m].list;
  684.     }
  685.     else
  686.     {
  687.         /* Use default model */
  688.         m = LoadModel ("light2.tri");
  689.         target[client[c].target].model = m;
  690.         target[client[c].target].list = model[m].list;
  691.     }
  692. }
  693.  
  694. ClientPosition (c, pkt, urgent)
  695. int c, urgent;
  696. char *pkt;
  697. /*
  698.  *  Client c is telling us where it is
  699.  */
  700. {
  701.     int t, cc;
  702.  
  703.     /* Get index of client's target */
  704.     t = client[c].target;
  705.  
  706.     /* Make unhidden */
  707.     target[t].hidden = 0;
  708.  
  709.     /* Parse packet */
  710.     if (18 != sscanf (pkt, "%*s %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
  711.         &target[t].pos[0], &target[t].pos[1], &target[t].pos[2],
  712.         &target[t].vel[0], &target[t].vel[1], &target[t].vel[2],
  713.         &target[t].view[0], &target[t].view[1], &target[t].view[2],
  714.         &target[t].up[0], &target[t].up[1], &target[t].up[2],
  715.         &target[t].move_up, &target[t].move_down,
  716.         &target[t].move_right, &target[t].move_left,
  717.         &target[t].move_pitchright, &target[t].move_pitchleft))
  718.     {
  719.         Log ("ClientPosition: Malformed POSN packet: %s", pkt);
  720.     }
  721.  
  722.     /* Set target's right vector */
  723.     Crossp (target[t].right, target[t].up, target[t].view);
  724.  
  725.     /* If it's urgent, we must tell other clients */
  726.     if (urgent)
  727.     {
  728.         for (cc=0; cc<NCLIENTS; cc++)
  729.         {
  730.             if (client[cc].active &&
  731.                 (cc != c) &&
  732.                 (cc != server.client) )
  733.             {
  734.                 client[cc].timer.posn[c] = 
  735.                     client[cc].posninterval;
  736.             }
  737.         }
  738.     }
  739. }
  740.  
  741. ClientBinaryPosition (c, pkt, urgent)
  742. int c, urgent;
  743. unsigned char *pkt;
  744. /*
  745.  *  Client c is telling us where it is
  746.  */
  747. {
  748.     int t, cc;
  749.  
  750.     /* Get index of client's target */
  751.     t = client[c].target;
  752.  
  753.     /* Make unhidden */
  754.     target[t].hidden = 0;
  755.  
  756.     /* Parse packet */
  757.     DecodeBinaryPacket (pkt, "VVvvffffff", target[t].pos, target[t].vel,
  758.         target[t].view, target[t].up,
  759.         &target[t].move_up, &target[t].move_down,
  760.         &target[t].move_right, &target[t].move_left,
  761.         &target[t].move_pitchright, &target[t].move_pitchleft);
  762.  
  763.     Normalize (target[t].up);
  764.     Normalize (target[t].view);
  765.  
  766.     /* Set target's right vector */
  767.     Crossp (target[t].right, target[t].up, target[t].view);
  768.  
  769.     /* If it's urgent, we must tell other clients */
  770.     if (urgent)
  771.     {
  772.         for (cc=0; cc<NCLIENTS; cc++)
  773.         {
  774.             if (client[cc].active &&
  775.                 (cc != c) &&
  776.                 (cc != server.client) )
  777.             {
  778.                 client[cc].timer.posn[c] = 
  779.                     client[cc].posninterval;
  780.             }
  781.         }
  782.     }
  783. }
  784.  
  785. ClientVersion (c, pkt)
  786. int c;
  787. char *pkt;
  788. /*
  789.  *  Client c is telling us what version it is running
  790.  */
  791. {
  792.     char buf[64];
  793.  
  794.     /* Extract version from packet */
  795.     if (1 != sscanf (pkt, "%*s %s", buf))
  796.     {
  797.         Log ("ClientVersion: Malformed VERS packet: %s", pkt);
  798.         return;
  799.     }
  800.  
  801.     /* Check version number */
  802.     if (strcmp (buf, VERSION))
  803.     {
  804.         /* Not the same, notify client */
  805.         SendASCIIPacket (client[c].socket,
  806.             "MESG Server is version %s, client is version %s",
  807.             VERSION, buf);
  808.         Log ("ClientVersion: Incompatible client version: %s", buf);
  809.         Cprint ("WARNING:  Client %d is using incompatible version: %s",
  810.             c, buf);
  811.     }
  812. }
  813.  
  814. ClientFire (c, pkt)
  815. int c;
  816. char *pkt;
  817. /*
  818.  *  Client c has sent a fire packet
  819.  */
  820. {
  821.     int t, w;
  822.  
  823.     /* Get client's target */
  824.     t = client[c].target;
  825.  
  826.     /* Parse packet */
  827.     if (1 != sscanf (pkt, "%*s %d", &w))
  828.     {
  829.         Log ("ClientFire: Malformed FIRE packet: %s", pkt);
  830.         return;
  831.     }
  832.  
  833.     /* Fire the missile */
  834.     FireMissile (target[t].pos, target[t].vel, target[t].view,
  835.         0, w, t);
  836.  
  837.     /* Tell everyone about it */
  838.     NetClientFires (c, w);
  839. }
  840.  
  841. SendPositions (clnt)
  842. int clnt;
  843. /*
  844.  *  THIS IS NOT CALLED!
  845.  *
  846.  *  Send a position report to client c
  847.  */
  848. {
  849.     int c, t1, t2;
  850.     double v[3], d;
  851.  
  852.     t1 = client[clnt].target;
  853.  
  854.     /* Loop through clients */
  855.     for (c=0; c<NCLIENTS; c++)
  856.     {
  857.         if (client[c].active)
  858.         {
  859.             /* Don't tell client about itself */
  860.             if (c == clnt) continue;
  861.             if (c == server.client) continue;
  862.  
  863.             t2 = client[c].target;
  864.  
  865.             /* Figure out how far away these clients are */
  866.             Vsub (v, target[t2].pos, target[t1].pos);
  867.             d = Mag2 (v);
  868.  
  869.             /* If far away, send short position packet */
  870.             if (d > TARG_MAXRANGE2)
  871.             {
  872.                 SendPositionShort (clnt, c);
  873.             }
  874.             else    /* Send long packet */
  875.             {
  876.                 SendPositionLong (clnt, c);
  877.             }
  878.         }
  879.     }
  880. }
  881.  
  882. SendPosition (clnt, c)
  883. int clnt, c;
  884. /*
  885.  *  Report c's position to clnt
  886.  */
  887. {
  888.     int t1, t2;
  889.     double v[3], d;
  890.  
  891.     if ((!client[clnt].active) || (!client[c].active)) return;
  892.  
  893.     t1 = client[clnt].target;
  894.     t2 = client[c].target;
  895.  
  896.     /* Determine distance */
  897.     Vsub (v, target[t2].pos, target[t1].pos);
  898.     d = Mag2 (v);
  899.  
  900.     if (d > TARG_MAXRANGE2)
  901.     {
  902.         SendPositionShort (clnt, c);
  903.     }
  904.     else
  905.     {
  906.         SendPositionLong (clnt, c);
  907.     }
  908. }
  909.  
  910. SendPositionShort (clnt, c)
  911. int clnt, c;
  912. /*
  913.  *  Send short position of client c to client clnt
  914.  */
  915. {
  916.     int t;
  917.  
  918.     t = client[c].target;
  919.  
  920. #ifdef BINARYPACKETS
  921.     SendBinaryPacket (client[clnt].socket, "ccVV", PKT_POSS, c,
  922.         target[t].pos, target[t].vel);
  923. #else
  924.     SendASCIIPacket (client[clnt].socket,
  925.         "POSS %d %lf %lf %lf %lf %lf %lf", c,
  926.         target[t].pos[0], target[t].pos[1], target[t].pos[2],
  927.         target[t].vel[0], target[t].vel[1], target[t].vel[2]);
  928. #endif
  929. }
  930.  
  931. SendPositionLong (clnt, c)
  932. int clnt, c;
  933. /*
  934.  *  Send long position of client c to client clnt
  935.  */
  936. {
  937.     int t;
  938.  
  939.     t = client[c].target;
  940.  
  941. #ifdef BINARYPACKETS
  942.     SendBinaryPacket (client[clnt].socket, "ccVVvvffffff", PKT_POSL, c,
  943.         target[t].pos, target[t].vel, target[t].view, target[t].up,
  944.         target[t].move_up, target[t].move_down,
  945.         target[t].move_right, target[t].move_left,
  946.         target[t].move_pitchright, target[t].move_pitchleft);
  947. #else
  948.     SendASCIIPacket (client[clnt].socket,
  949.         "POSL %d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", c,
  950.         target[t].pos[0], target[t].pos[1], target[t].pos[2],
  951.         target[t].vel[0], target[t].vel[1], target[t].vel[2],
  952.         target[t].view[0], target[t].view[1], target[t].view[2],
  953.         target[t].up[0], target[t].up[1], target[t].up[2],
  954.         target[t].move_up, target[t].move_down,
  955.         target[t].move_right, target[t].move_left,
  956.         target[t].move_pitchright, target[t].move_pitchleft);
  957. #endif
  958. }
  959.  
  960. SendPlanets (c)
  961. int c;
  962. /*
  963.  *  Send planet positions to client
  964.  */
  965. {
  966.     int p;
  967.  
  968.     for (p=0; p<NPLANETS; p++)
  969.     {
  970. #ifdef BINARYPACKETS
  971.         SendBinaryPacket (client[c].socket, "ccF", PKT_PLAN, p, planet[p].theta);
  972. #else
  973.         SendASCIIPacket (client[c].socket, "PLAN %d %lf", p, planet[p].theta);
  974. #endif
  975.     }
  976.  
  977.     SendASCIIPacket (client[c].socket, "RPLN");
  978. }
  979.  
  980. SendRollCall (c)
  981. /*
  982.  *  Send roll call to client c
  983.  */
  984. {
  985.     int cc, t;
  986.  
  987.     /* Reset timer */
  988.     client[c].timer.rollcall = 0.0;
  989.  
  990.     for (cc=0; cc<NCLIENTS; cc++)
  991.     {
  992.         /* Send name if client active */
  993.         if (client[cc].active)
  994.         {
  995.             t = client[cc].target;
  996.  
  997.             if (t >= 0)
  998.             {
  999.                 /* Send name */
  1000.                 SendASCIIPacket (client[c].socket,
  1001.                     "NAME %d %s %d", cc, target[t].name, client[cc].frags);
  1002.  
  1003.                 /* Send model */
  1004.                 if (cc != server.client)
  1005.                 {
  1006.                     SendASCIIPacket (client[c].socket,
  1007.                         "MODL %d %s", cc, model[target[t].model].name);
  1008.                 }
  1009.                 else
  1010.                 {
  1011.                     SendASCIIPacket (client[c].socket,
  1012.                         "MODL %d %s", cc, player.model);
  1013.                 }
  1014.             }
  1015.         }
  1016.         else
  1017.         {
  1018. #ifndef BINARYPACKETS
  1019.             /* Show unused */
  1020.             SendASCIIPacket (client[c].socket,
  1021.                 "VCNT %d", cc);
  1022. #endif
  1023.         }
  1024.     }
  1025.  
  1026. #ifdef BINARYPACKETS
  1027.     /* Send vacant slots to client */
  1028.     SendBinaryVacant (c);
  1029. #endif
  1030.  
  1031.     /* Send flags while we're here */
  1032.     SendFlags (c);
  1033.  
  1034.     /* Oh and what the heck, let's send planet positions too */
  1035.     SendPlanets (c);
  1036. }
  1037.  
  1038. SendBinaryVacant (c)
  1039. /*
  1040.  *  Send binary vacancy report to client c
  1041.  */
  1042. {
  1043.     int cc;
  1044.     unsigned int w, bit, i1, i2;
  1045.  
  1046.     w = 0;
  1047.     bit = 1;
  1048.  
  1049.     /* Make bitmask */
  1050.     for (cc=0; cc<NCLIENTS; cc++)
  1051.     {
  1052.         if (client[cc].active) w += bit;
  1053.         bit = bit * 2;
  1054.     }
  1055.  
  1056.     /* Split into bytes */
  1057.     i1 = w % 256;
  1058.     i2 = w / 256;
  1059.  
  1060.     /* Send the packet */
  1061.     SendBinaryPacket (client[c].socket, "ccc", PKT_VCNT, i1, i2);
  1062. }
  1063.  
  1064. ClientChat (c, pkt)
  1065. int c;
  1066. char *pkt;
  1067. /*
  1068.  *  Client sent chat message
  1069.  */
  1070. {
  1071.     int cc;
  1072.  
  1073.     /* Sanity */
  1074.     if ( (pkt[4] == 0) || (pkt[5] == 0) || (strlen(pkt) > TEXTSIZE) ) return;
  1075.  
  1076.     /* Show the message to us */
  1077.     Cprint ("%s: %s", target[client[c].target].name, &pkt[5]);
  1078.     if (sound) PlayAudio (SOUND_COMM);
  1079.  
  1080.     /* Send to other clients */
  1081.     for (cc=0; cc<NCLIENTS; cc++)
  1082.     {
  1083.         if (client[cc].active && (cc != server.client) && (cc != c) )
  1084.         {
  1085.             SendASCIIPacket (client[cc].socket, "CMSG %s: %s",
  1086.                 target[client[c].target].name, &pkt[5]);
  1087.         }
  1088.     }
  1089. }
  1090.  
  1091. SendFlags()
  1092. /*
  1093.  *  Send gravity, etc., flags to clients
  1094.  */
  1095. {
  1096.     int c, f;
  1097.  
  1098.     /* Set flags */
  1099.     f = 0;
  1100.     if (gravity) f |= FLAG_GRAVITY;
  1101.     if (player.flightmodel == FLIGHT_ARCADE) f |= FLAG_FLIGHTMODEL;
  1102.     if (fullstop) f |= FLAG_FULLSTOP;
  1103.     if (realdistances) f |= FLAG_REALDISTANCES;
  1104.     if (orbit) f |= FLAG_ORBIT;
  1105.  
  1106.     /* Send em */
  1107.     for (c=0; c<NCLIENTS; c++)
  1108.     {
  1109.         if (client[c].active && (c != server.client) )
  1110.         {
  1111.             SendASCIIPacket (client[c].socket, "FLAG %d", f);
  1112.         }
  1113.     }
  1114. }
  1115.  
  1116. void DoDrop (void)
  1117. /*
  1118.  *  Server admin wants to drop a client
  1119.  */
  1120. {
  1121.     int c;
  1122.  
  1123.     if (!am_server) return;
  1124.  
  1125.     c = atoi (text.buf);
  1126.  
  1127.     /* Check and drop if okay */
  1128.     if ( (c < 0) || (c >= NCLIENTS) || (!client[c].active) ||
  1129.         client[c].is_me)
  1130.     {
  1131.         Mprint ("No such client: %d", c);
  1132.         return;
  1133.     }
  1134.  
  1135.     DropClient (c);
  1136.     Cprint ("Dropped client %d", c);
  1137. }
  1138.