home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Network.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-22  |  9.6 KB  |  412 lines

  1. #include "Network.h"
  2.  
  3. #include "log.h"
  4. #include "Gui.h"
  5.  
  6. //#include "SDL/SDL_net.h"
  7. //#include "Server.h"
  8. //#include "Client.h"
  9. #include "Game.h"
  10. #include "PacketHandler.h"
  11.  
  12. Server* Network::server = NULL;
  13. Client* Network::client = NULL;
  14.  
  15.  
  16. bool Network::initialized = false;
  17. bool Network::serverInitialized = false;
  18. bool Network::clientInitialized = false;
  19.  
  20. bool Network::init(){
  21.     if(initialized){
  22.         error("(in Net::init()): Network is already initialized.\n\n");
  23.         return false;
  24.     }
  25.  
  26.     if(Gui::loadingMenu!=NULL)
  27.         Gui::loadingMenu->updateStatusBar("initializing net");
  28.  
  29.     log("\n");
  30.     log("****************************\n");
  31.     log("*** Initializing Network ***\n");
  32.     log("****************************\n");
  33.     log("\n");
  34.  
  35.     log("Initializing SDLNet interface...\n");
  36.     if( SDLNet_Init() == -1){
  37.         error("(in Net::init()): SDLNet_Init() failed: %s.\n\n", SDLNet_GetError());
  38.         return false;
  39.     }
  40.  
  41.     initialized = true;
  42.  
  43.     return true;
  44. }
  45.  
  46. bool Network::shutdown(){
  47.     if(!initialized){
  48.         error("(in Network::shutdown()): Network is not initialized.\n\n");
  49.         return false;
  50.     }
  51.  
  52.     log("\n");
  53.     log("=============================\n");
  54.     log("=== Shutting down Network ===\n");
  55.     log("=============================\n");
  56.     log("\n");
  57.  
  58.     if(wasClientInit()){
  59.         log("Shutting down client...\n");
  60.         if( !shutdownClient() ){
  61.             return false;
  62.         }
  63.     }
  64.  
  65.     if(wasServerInit()){
  66.         log("Shutting down server...\n");
  67.         if( !shutdownServer() ){
  68.             return false;
  69.         }
  70.     }
  71.  
  72.     log("Shutting down SDLNet interface...\n");
  73.     SDLNet_Quit();
  74.  
  75.     initialized = false;
  76.  
  77.     return true;
  78. }
  79.  
  80. bool Network::wasInit(){
  81.     return initialized;
  82. }
  83.  
  84. bool Network::initServer(){
  85.     if(serverInitialized){
  86.         error("(in Network::startServer()): There is already a server running on this machine.\n\n");
  87.         return false;
  88.     }
  89.  
  90.     log("\n");
  91.     log("***************************\n");
  92.     log("*** Initializing Server ***\n");
  93.     log("***************************\n");
  94.     log("\n");
  95.  
  96.     info.cvar.network_server_name->updateVar();
  97.     info.cvar.network_server_description->updateVar();
  98.     info.cvar.network_server_hostName->updateVar();
  99.     info.cvar.network_server_port->updateVar();
  100.     info.cvar.network_server_maxClients->updateVar();
  101.  
  102.     server = new Server();
  103.  
  104.     if( !Game::info.var.clientGame ){    // not a client game -> open server port
  105.         if(server->openPort()){
  106.             log("Port opened (UDP: %i).\n", info.var.server_port);
  107.         }else{
  108.             error("in Network::initServer(): Couldn't open server port (UDP: %i).\n\n", info.var.server_port);
  109.             return false;
  110.         }
  111.         log("Server ready.\n");
  112.     }else{    // client game -> just prepare a shadow server
  113.         if(SDLNet_ResolveHost(&server->ipAddress, info.var.server_hostName, info.var.server_port) == -1){
  114.             //error("(in Network::initServer()): SDLNet_ResolveHost() failed: %s.\n\n", SDLNet_GetError());
  115.             error("(in Network::initServer()): Unknown host: '%s'.\n\n", info.var.server_hostName);
  116.             return false;
  117.         }else{
  118.             char buff[128];
  119.             Network::ipAddressToString(server->ipAddress, buff);
  120.             log("Hostname '%s' resolved. IP: '%s'\n", info.var.server_hostName, buff);
  121.         }
  122.         log("Prepared shadow server for client game.\n");
  123.     }
  124.  
  125.     serverInitialized = true;
  126.  
  127.     return true;
  128. }
  129.  
  130. bool Network::shutdownServer(){
  131.     if( !serverInitialized ){
  132.         error("(in Network::shutdownServer()): No server running on this machine.\n\n");
  133.         return false;
  134.     }
  135.  
  136.     log("\n");
  137.     log("============================\n");
  138.     log("=== Shutting down Server ===\n");
  139.     log("============================\n");
  140.     log("\n");
  141.  
  142.     if( !Game::info.var.clientGame ){
  143.         log("Disconnecting clients...\n");
  144.         if( !server->disconnectAllClients("Server is shutting down.") ){
  145.             error("(in Network::shutdownServer()): server->disconnect failed.\n\n");
  146.             return false;
  147.         }
  148.     
  149.         log("Closing port...\n");
  150.         if( !server->closePort() ){
  151.             error("(in Network::shutdownServer()): server->closePort failed.\n\n");
  152.             return false;
  153.         }
  154.  
  155.         log("Server down.\n");
  156.     }else{
  157.         log("Shadow server down.\n");
  158.     }
  159.  
  160.     delete server;
  161.     server = NULL;
  162.     
  163.     serverInitialized = false;
  164.  
  165.     return true;
  166. }
  167.  
  168. bool Network::wasServerInit(){
  169.     return serverInitialized;
  170. }
  171.  
  172.  
  173.  
  174. bool Network::initClient(){
  175.     if( clientInitialized ){
  176.         error("(in Network::initClient()): There is already a client running on this machine.\n\n");
  177.         return false;
  178.     }
  179.     
  180.     log("\n");
  181.     log("***************************\n");
  182.     log("*** Initializing Client ***\n");
  183.     log("***************************\n");
  184.     log("\n");
  185.  
  186.     info.cvar.network_client_ip->updateVar();
  187.     info.cvar.network_client_port->updateVar();
  188.  
  189.     client = new Client();
  190.  
  191.     if(client->openPort()){
  192.         log("Port opened (UDP: %d).\n", info.var.client_port);
  193.     }else{
  194.         error("(in Network::initClient()): Couldn't open clientPort  (UDP: %d).\n\n", info.var.client_port);
  195.         return false;
  196.     }
  197.  
  198.     log("Client ready.\n");
  199.     clientInitialized = true;
  200.  
  201.     return true;
  202. }
  203.  
  204. bool Network::shutdownClient(){
  205.     if( !clientInitialized ){
  206.         error("(in Network::shutdownClient()): No client running on this machine.\n\n");
  207.         return false;
  208.     }
  209.  
  210.     log("\n");
  211.     log("============================\n");
  212.     log("=== Shutting down Client ===\n");
  213.     log("============================\n");
  214.     log("\n");
  215.  
  216.     if( Game::info.var.clientGame && client->clientId != -1){    // client game and conencted
  217.         log("Disconnecting from server...\n");
  218.         if( !client->disconnect() ){
  219.             error("(in Network::shutdownClient()): client->disconnect failed.\n\n");
  220.             return false;
  221.         }
  222.     }else{        // local client or not conected
  223.         //Network::server->removeClient(Network::client);
  224.  
  225.     }
  226.  
  227.     log("Closing port...\n");
  228.     if( !client->closePort() ){
  229.         error("(in Network::shutdownClient()): client->closePort failed.\n\n");
  230.         return false;
  231.     }
  232.  
  233.     delete client;
  234.     client = NULL;
  235.     
  236.     clientInitialized = false;
  237.  
  238.     log("Client down.\n");
  239.  
  240.     return true;
  241. }
  242.  
  243. bool Network::wasClientInit(){
  244.     return clientInitialized;
  245. }
  246.  
  247.  
  248.  
  249. bool Network::registerCVarsAndCCmds(){
  250.  
  251.     return info.registerCVarsAndCCmds();
  252. }
  253.  
  254. bool Network::unregisterCVarsAndCCmds(){
  255.     return info.unregisterCVarsAndCCmds();
  256. }
  257.  
  258.  
  259.  
  260.  
  261.  
  262.  
  263.  
  264.  
  265.  
  266.  
  267. void Network::sendAndReceive(){
  268.  
  269.     if(clientInitialized){
  270.         client->sendPackets();
  271.         client->receivePackets();
  272.     }
  273.  
  274.     if(serverInitialized && !Game::info.var.clientGame){
  275.         server->sendPackets();
  276.         server->receivePackets();
  277.     }
  278. }
  279.  
  280. bool Network::makeLoopbackConnection(){
  281.     if( !serverInitialized ){
  282.         error("(in Network::makeLoopbackConnection()): No server running on this machine.\n\n");
  283.         return false;
  284.     }
  285.  
  286.     if( !clientInitialized ){
  287.         error("(in Network::makeLoopbackConnection()): No client running on this machine.\n\n");
  288.         return false;
  289.     }
  290.  
  291.     log("Making loopback connection to '%s' (%s:%d)...\n", info.var.server_name, info.var.server_ip, info.var.server_port);
  292.  
  293.     client->clientId = server->addClient(client);    // should be 0
  294.     server->localClient = client;
  295.  
  296.     // send test packet
  297.  
  298.     UDPpacket* p = SDLNet_AllocPacket(2);
  299.     if( p == NULL ){
  300.         error("(in Network::makeLoopbackConnection()): Couldn't alloc packet.\n\n");
  301.         return false;
  302.     }
  303.  
  304.     p->address.host = server->ipAddress.host;
  305.     p->address.port = server->ipAddress.port;
  306.  
  307.     p->data[0] = (unsigned char)NETWORK_FWP_PACKET_ID;
  308.     p->data[1] = (unsigned char)PACKET_TYPE_PING;
  309.  
  310.     p->channel = -1;
  311.     p->len = 2;
  312.  
  313.     for(int i=0;i<info.var.client_maxConnectionAttempts;i++){
  314.  
  315.         log("Sending test packet (try %i)...\n", i+1);
  316.         if( !sendPacket(client->socket, p) ){
  317.             error("(in Network::makeLoopbackConnection()): Couldn't send packet.\n\n");
  318.             SDLNet_FreePacket(p);
  319.             return false;
  320.         }
  321.  
  322.         UDPpacket* answer = NULL;
  323.         do{
  324.             answer = Network::receivePacket(server->socket);
  325.             if( answer != NULL ){
  326.                 if(answer->data[1] == PACKET_TYPE_PING){
  327.                     log("Received test packet.\n");
  328.  
  329.                     client->ipAddress.host = answer->address.host;
  330.                     client->ipAddress.port = answer->address.port;
  331.  
  332.                     SDLNet_FreePacket(answer);
  333.                     SDLNet_FreePacket(p);
  334.  
  335.                     log("Loopback connection established.");
  336.  
  337.  
  338.                     return true;
  339.                 }else{
  340.                     warn("(in Network::makeLoopbackConnection()): Received unexpected packet from server.\n\n");
  341.                     SDLNet_FreePacket(answer);
  342.                 }
  343.             }
  344.         }while( answer != NULL );
  345.     }
  346.  
  347.     SDLNet_FreePacket(p);
  348.     error("(in Network::makeLoopbackConnection()): Couldn't receive test packet. Giving up.\n\n");
  349.     return false;
  350.  
  351. }
  352.  
  353.  
  354. bool Network::sendPacket(UDPsocket socket, UDPpacket* p){
  355.     int n = SDLNet_UDP_Send(socket, -1, p);
  356.     if( n == 0 ){
  357.         return false;
  358.     }
  359.  
  360.     return true;
  361. }
  362.  
  363. bool Network::sendAndFreePacket(UDPsocket socket, UDPpacket* p){
  364.     int n = SDLNet_UDP_Send(socket, -1, p);
  365.     SDLNet_FreePacket(p);
  366.     if( n == 0 ){
  367.         return false;
  368.     }
  369.  
  370.     return true;
  371. }
  372.  
  373. UDPpacket* Network::receivePacket(UDPsocket socket){
  374.     UDPpacket* p = SDLNet_AllocPacket(NETWORK_MAX_PACKET_SIZE);
  375.     if(p == NULL){
  376.         error("(in Network::receivePacket()): Couldn't alloc packet.\n\n");
  377.         return NULL;
  378.     }
  379.     int n = SDLNet_UDP_Recv(socket, p);
  380.     if(n == 1){            // ok
  381.         if(p->len >= 2 && p->data[0] == NETWORK_FWP_PACKET_ID && p->data[1] < NUM_PACKET_TYPES){
  382.             return p;
  383.         }else{
  384.             return NULL;
  385.         }
  386.  
  387.     }else if(n == 0){    // nothing received
  388.         return NULL;
  389.     }else if(n == -1){    // error
  390.         error("(in Network::receivePacket()): SDLNet_UDP_Recv() failed: %s.\n\n", SDLNet_GetError());
  391.         return NULL;
  392.     }else{
  393.         return NULL;
  394.     }
  395. }
  396.  
  397. void Network::ipAddressToString(IPaddress ip, char* buff){
  398.     char tmp[64];
  399.  
  400.     buff[0] = '\0';
  401.     sprintf(tmp, "%d.", (ip.host & 0x000000FF));
  402.     strcat(buff, tmp);
  403.     sprintf(tmp, "%d.", (ip.host & 0x0000FF00) >> 8);
  404.     strcat(buff, tmp);
  405.     sprintf(tmp, "%d.", (ip.host & 0x00FF0000) >> 16);
  406.     strcat(buff, tmp);
  407.     sprintf(tmp, "%d:", (ip.host & 0xFF000000) >> 24);
  408.     strcat(buff, tmp);
  409.     sprintf(tmp, "%d", ip.port);
  410.     strcat(buff, tmp);
  411. }
  412.