Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.62 KB | None | 0 0
  1. // client.cpp, mostly network related client game code
  2.  
  3. #include "engine.h"
  4.  
  5. ENetHost *clienthost = NULL;
  6. ENetPeer *curpeer = NULL, *connpeer = NULL;
  7. int connmillis = 0, connattempts = 0, discmillis = 0;
  8.  
  9. bool multiplayer(bool msg)
  10. {
  11.     bool val = curpeer || hasnonlocalclients();
  12.     if(val && msg) conoutf(CON_ERROR, "operation not available in multiplayer");
  13.     return val;
  14. }
  15.  
  16. void setrate(int rate)
  17. {
  18.    if(!curpeer) return;
  19.    enet_host_bandwidth_limit(clienthost, rate*1024, rate*1024);
  20. }
  21.  
  22. VARF(rate, 0, 0, 1024, setrate(rate));
  23.  
  24. void throttle();
  25.  
  26. VARF(throttle_interval, 0, 5, 30, throttle());
  27. VARF(throttle_accel,    0, 2, 32, throttle());
  28. VARF(throttle_decel,    0, 2, 32, throttle());
  29.  
  30. void throttle()
  31. {
  32.     if(!curpeer) return;
  33.     ASSERT(ENET_PEER_PACKET_THROTTLE_SCALE==32);
  34.     enet_peer_throttle_configure(curpeer, throttle_interval*1000, throttle_accel, throttle_decel);
  35. }
  36.  
  37. bool isconnected(bool attempt, bool local)
  38. {
  39.     return curpeer || (attempt && connpeer) || (local && haslocalclients());
  40. }
  41.  
  42. ICOMMAND(isconnected, "bb", (int *attempt, int *local), intret(isconnected(*attempt > 0, *local != 0) ? 1 : 0));
  43.  
  44. const ENetAddress *connectedpeer()
  45. {
  46.     return curpeer ? &curpeer->address : NULL;
  47. }
  48.  
  49. ICOMMAND(connectedip, "", (),
  50. {
  51.     const ENetAddress *address = connectedpeer();
  52.     cubestr hostname;
  53.     result(address && enet_address_get_host_ip(address, hostname, sizeof(hostname)) >= 0 ? hostname : "");
  54. });
  55.  
  56. ICOMMAND(connectedport, "", (),
  57. {
  58.     const ENetAddress *address = connectedpeer();
  59.     intret(address ? address->port : -1);
  60. });
  61.  
  62. void abortconnect()
  63. {
  64.     if(!connpeer) return;
  65.     game::connectfail();
  66.     if(connpeer->state!=ENET_PEER_STATE_DISCONNECTED) enet_peer_reset(connpeer);
  67.     connpeer = NULL;
  68.     if(curpeer) return;
  69.     enet_host_destroy(clienthost);
  70.     clienthost = NULL;
  71. }
  72.  
  73. SVARP(connectname, "");
  74. VARP(connectport, 0, 0, 0xFFFF);
  75.  
  76. void connectserv(const char *servername, int serverport, const char *serverpassword)
  77. {
  78.     if(connpeer)
  79.     {
  80.         conoutf("aborting connection attempt");
  81.         abortconnect();
  82.     }
  83.  
  84.     if(serverport <= 0) serverport = server::serverport();
  85.  
  86.     ENetAddress address;
  87.     address.port = serverport;
  88.  
  89.     if(servername)
  90.     {
  91.         if(strcmp(servername, connectname)) setsvar("connectname", servername);
  92.         if(serverport != connectport) setvar("connectport", serverport);
  93.         addserver(servername, serverport, serverpassword && serverpassword[0] ? serverpassword : NULL);
  94.         conoutf("attempting to connect to %s:%d", servername, serverport);
  95.         if(!resolverwait(servername, &address))
  96.         {
  97.             conoutf("\f3could not resolve server %s", servername);
  98.             return;
  99.         }
  100.     }
  101.     else
  102.     {
  103.         setsvar("connectname", "");
  104.         setvar("connectport", 0);
  105.         conoutf("attempting to connect over LAN");
  106.         address.host = ENET_HOST_BROADCAST;
  107.     }
  108.  
  109.     if(!clienthost)
  110.     {
  111.         clienthost = enet_host_create(NULL, 2, server::numchannels(), rate*1024, rate*1024);
  112.         if(!clienthost)
  113.         {
  114.             conoutf("\f3could not connect to server");
  115.             return;
  116.         }
  117.         clienthost->duplicatePeers = 0;
  118.     }
  119.  
  120.     connpeer = enet_host_connect(clienthost, &address, server::numchannels(), 0);
  121.     enet_host_flush(clienthost);
  122.     connmillis = totalmillis;
  123.     connattempts = 0;
  124.  
  125.     game::connectattempt(servername ? servername : "", serverpassword ? serverpassword : "", address);
  126. }
  127.  
  128. void reconnect(const char *serverpassword)
  129. {
  130.     if(!connectname[0] || connectport <= 0)
  131.     {
  132.         conoutf(CON_ERROR, "no previous connection");
  133.         return;
  134.     }
  135.  
  136.     connectserv(connectname, connectport, serverpassword);
  137. }
  138.  
  139. void disconnect(bool async, bool cleanup)
  140. {
  141.     if(curpeer)
  142.     {
  143.         if(!discmillis)
  144.         {
  145.             enet_peer_disconnect(curpeer, DISC_NONE);
  146.             enet_host_flush(clienthost);
  147.             discmillis = totalmillis;
  148.         }
  149.         if(curpeer->state!=ENET_PEER_STATE_DISCONNECTED)
  150.         {
  151.             if(async) return;
  152.             enet_peer_reset(curpeer);
  153.         }
  154.         curpeer = NULL;
  155.         discmillis = 0;
  156.         conoutf("disconnected");
  157.         game::gamedisconnect(cleanup);
  158.         mainmenu = 1;
  159.     }
  160.     if(!connpeer && clienthost)
  161.     {
  162.         enet_host_destroy(clienthost);
  163.         clienthost = NULL;
  164.     }
  165. }
  166.  
  167. void trydisconnect(bool local)
  168. {
  169.     if(connpeer)
  170.     {
  171.         conoutf("aborting connection attempt");
  172.         abortconnect();
  173.     }
  174.     else if(curpeer)
  175.     {
  176.         conoutf("attempting to disconnect...");
  177.         disconnect(!discmillis);
  178.     }
  179.     else if(local && haslocalclients()) localdisconnect();
  180.     else conoutf("not connected");
  181. }
  182.  
  183. ICOMMAND(connect, "sis", (char *name, int *port, char *pw), connectserv(name, *port, pw));
  184. ICOMMAND(lanconnect, "is", (int *port, char *pw), connectserv(NULL, *port, pw));
  185. COMMAND(reconnect, "s");
  186. ICOMMAND(disconnect, "b", (int *local), trydisconnect(*local != 0));
  187. ICOMMAND(localconnect, "", (), { if(!isconnected()) localconnect(); });
  188. ICOMMAND(localdisconnect, "", (), { if(haslocalclients()) localdisconnect(); });
  189.  
  190. void sendclientpacket(ENetPacket *packet, int chan)
  191. {
  192.     if(curpeer) enet_peer_send(curpeer, chan, packet);
  193.     else localclienttoserver(chan, packet);
  194. }
  195.  
  196. void flushclient()
  197. {
  198.     if(clienthost) enet_host_flush(clienthost);
  199. }
  200.  
  201. void neterr(const char *s, bool disc)
  202. {
  203.     conoutf(CON_ERROR, "\f3illegal network message (%s)", s);
  204.     if(disc) disconnect();
  205. }
  206.  
  207. void localservertoclient(int chan, ENetPacket *packet)   // processes any updates from the server
  208. {
  209.     packetbuf p(packet);
  210.     game::parsepacketclient(chan, p);
  211. }
  212.  
  213. void clientkeepalive() { if(clienthost) enet_host_service(clienthost, NULL, 0); }
  214.  
  215. void gets2c()           // get updates from the server
  216. {
  217.     ENetEvent event;
  218.     if(!clienthost) return;
  219.     if(connpeer && totalmillis/3000 > connmillis/3000)
  220.     {
  221.         conoutf("attempting to connect...");
  222.         connmillis = totalmillis;
  223.         ++connattempts;
  224.         if(connattempts > 3)
  225.         {
  226.             conoutf("\f3could not connect to server");
  227.             abortconnect();
  228.             return;
  229.         }
  230.     }
  231.     while(clienthost && enet_host_service(clienthost, &event, 0)>0)
  232.     switch(event.type)
  233.     {
  234.         case ENET_EVENT_TYPE_CONNECT:
  235.             disconnect(false, false);
  236.             localdisconnect(false);
  237.             curpeer = connpeer;
  238.             connpeer = NULL;
  239.             conoutf("connected to server");
  240.             throttle();
  241.             if(rate) setrate(rate);
  242.             game::gameconnect(true);
  243.             break;
  244.  
  245.         case ENET_EVENT_TYPE_RECEIVE:
  246.             if(discmillis) conoutf("attempting to disconnect...");
  247.             else localservertoclient(event.channelID, event.packet);
  248.             enet_packet_destroy(event.packet);
  249.             break;
  250.  
  251.         case ENET_EVENT_TYPE_DISCONNECT:
  252.             if(event.data>=DISC_NUM) event.data = DISC_NONE;
  253.             if(event.peer==connpeer)
  254.             {
  255.                 conoutf("\f3could not connect to server");
  256.                 abortconnect();
  257.             }
  258.             else
  259.             {
  260.                 if(!discmillis || event.data)
  261.                 {
  262.                     const char *msg = disconnectreason(event.data);
  263.                     if(msg) conoutf("\f3server network error, disconnecting (%s) ...", msg);
  264.                     else conoutf("\f3server network error, disconnecting...");
  265.                 }
  266.                 disconnect();
  267.             }
  268.             return;
  269.  
  270.         default:
  271.             break;
  272.     }
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement