home *** CD-ROM | disk | FTP | other *** search
/ Enter 2005 March / ENTER.ISO / files / fwp-0.0.6-win32-installer.exe / Client.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-24  |  30.4 KB  |  1,006 lines

  1. #include "Client.h"
  2.  
  3.  
  4. #include "Network.h"
  5. //#include "PacketHandler.h"
  6. #include "log.h"
  7. #include "Server.h"
  8. #include "Game.h"
  9. #include "Gui.h"
  10.  
  11. Client::Client(){
  12.     //ipAddress = NULL;
  13.     socket = NULL;
  14.  
  15.     clientId = -1;    // not connected
  16. //    ping = 0;
  17.     lastPingMillis = SDL_GetTicks();
  18.     momentOfConnectMillis = SDL_GetTicks();
  19. //    secondsOnServer = 0;
  20.     lastClientstateMillis = SDL_GetTicks();
  21.     nextSpawnMillis = 0;
  22.     lastSpawnMillis = 0;
  23. //    isReady = false;
  24.  
  25.     strcpy(ci.name, Game::info.var.player_name);    // will be changed upon connect
  26.     ci.ping = 0;
  27.     ci.secondsOnServer = 0;
  28.     ci.team = GAME_TEAM_SPECTATORS;
  29.     ci.score = 0;
  30.     ci.kills = 0;
  31.     ci.deaths = 0;
  32.     ci.vehicle = Game::info.var.player_vehicle;    // THINKABOUTME: oder alles auf 0?
  33.     ci.weapon1 = Game::info.var.player_weapon1;
  34.     ci.weapon2 = Game::info.var.player_weapon2;
  35.     ci.weapon3 = Game::info.var.player_weapon3;
  36.     ci.weapon4 = Game::info.var.player_weapon4;
  37.  
  38.     
  39.     cs.armor = 0;
  40.     cs.energy = 0;
  41.     vectorInit3d(0.0f, 0.0f, 0.0f, cs.pos);
  42.     vectorInit3d(0.0f, 0.0f, 0.0f, cs.dir);
  43.     vectorInit3d(0.0f, 0.0f, 0.0f, cs.up);
  44.     vectorInit3d(0.0f, 0.0f, 0.0f, cs.vel);
  45.  
  46.     vehicle = NULL;
  47. }
  48.  
  49. Client::~Client(){
  50.     if( vehicle != NULL ){
  51.         Game::unspawnVehicle(vehicle);
  52.     }
  53. }
  54.  
  55. void Client::setName(char* newName){
  56.     strncpy(ci.name, newName, CLIENT_MAX_NAME_LENGTH-1);
  57.     ci.name[CLIENT_MAX_NAME_LENGTH-1] = '\0';
  58. }
  59.  
  60. bool Client::openPort(){
  61.     socket = SDLNet_UDP_Open(Network::info.var.client_port);
  62.     if(socket == NULL){
  63.         error("(in Client::openPort()): SDLNet_UDP_Open() failed: %s.\n\n", SDLNet_GetError());
  64.         return false;
  65.     }
  66.  
  67.     if(SDLNet_ResolveHost(&ipAddress, Network::info.var.client_ip, Network::info.var.client_port) == -1){
  68.         error("(in Client::openPort()): SDLNet_ResolveHost() failed: %s.\n\n", SDLNet_GetError());
  69.         SDLNet_UDP_Close(socket);
  70.         return false;
  71.     }
  72.  
  73. //    IPaddress* ip = SDLNet_UDP_GetPeerAddress(socket, -1);
  74. //    ipAddress.host = ip->host;
  75. //    ipAddress.port = ip->port;
  76. //    printf("host: %d, port: %d\n", ipAddress.host, ipAddress.port);
  77. //    ipAddress.host = 0x0100007F;
  78. //    ipAddress.port = Network::info.var.clientPort;
  79.     
  80. //    printf("client addr: %s:%d\n", SDLNet_ResolveIP(&ipAddress), ipAddress.port);
  81.  
  82.     return true;
  83. }
  84.  
  85. bool Client::closePort(){
  86.     SDLNet_UDP_Close(socket);
  87.     return true;
  88. }
  89.  
  90. bool Client::connect(){
  91.     connectionRequestPacket_t cr;
  92.     cr.protocolVersion = NETWORK_PROTOCOL_VERSION;
  93.     strncpy(cr.name, ci.name, CLIENT_MAX_NAME_LENGTH);
  94.  
  95.     for(int i=0;i<Network::info.var.client_maxConnectionAttempts;i++){
  96.  
  97.         // alloc packet to send
  98.         UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CONNECTION_REQUEST, Network::server->ipAddress, &cr, sizeof(cr));
  99.         if(p == NULL){
  100.             error("(in Client::connect()): Couldn't alloc packet.\n\n");
  101.             return false;
  102.         }
  103.  
  104.         // send request
  105.         if( !Network::sendAndFreePacket(socket, p) ){
  106.             error("(in Client::connect()): Couldn't send packet.\n\n");
  107.             return false;
  108.         }
  109.  
  110.         log("Connection request send to %s:%i (Try %i). Waiting for reply...\n", Network::info.var.server_ip, Network::info.var.server_port, i+1);
  111.         SDL_Delay(1000);
  112.         
  113.         // wait for answer
  114.         UDPpacket* answer = NULL;
  115.         do{
  116.             answer = Network::receivePacket(socket);
  117.             if( answer != NULL ){
  118.                 if(answer->data[1] == PACKET_TYPE_CONNECTION_REQUEST_ACCEPTED){
  119.                     log("Connection accepted by server.\n");
  120.  
  121.                     connectionRequestAcceptedPacket_t ca;
  122.                     PacketHandler::unwrapAndFreePacket(answer, &ca, sizeof(ca));
  123.  
  124. //                    Game::info.cvar.game_player_name->setValStr(ca.newName);
  125. //                    Game::info.cvar.game_player_name->updateVar();
  126.                     strcpy(Game::info.var.player_name, ca.newName);
  127.  
  128.                     // handle si part
  129.                     strcpy(Game::info.var.arena, ca.si.arena);
  130.                     Game::info.var.mode = ca.si.gamemode;
  131.                     strcpy(Network::info.var.server_name, ca.si.name);
  132.                     strcpy(Network::info.var.server_description, ca.si.description);
  133.                     Network::info.var.server_maxClients = ca.si.maxClients;
  134.                     Game::info.var.ghostTime = ca.si.ghostTime;
  135.                     if( ca.si.optionFlags & PACKET_OPTION_FLAG_GAME_USE_ARENA_CYCLE )
  136.                         Game::info.var.useArenaCycle = true;
  137.                     if( ca.si.optionFlags & PACKET_OPTION_FLAG_GAME_ENABLE_FRIENDLY_FIRE )
  138.                         Game::info.var.enableFriendlyFire = true;
  139.  
  140.                     Network::server->si = ca.si;
  141.  
  142.                     // add self to shadow server    
  143.                     this->setName(ca.newName);
  144.                     this->clientId = ca.clientId;
  145.                     Network::server->clients[ca.clientId] = this;
  146. //                    this->team = Network::server->addClientToTeam(this, GAME_TEAM_SPECTATORS);
  147.  
  148.                     // handle pi part (add other clients)
  149.                     for(int j=0;j<Network::server->si.maxClients;j++){
  150.                         if(ca.pi.clientIds[j] != -1){
  151.                             Client* c;
  152.                             if(Network::server->clients[j] == this){
  153.                                 c = this;
  154.                             }else{
  155.                                 c = new Client();
  156.                             }
  157.                             
  158.                             c->ci = ca.pi.ci[j];
  159.                             Network::server->clients[j] = c;
  160.  
  161.                             log("Added client '%s' to shadow server.\n", c->ci.name);
  162.                             // THINKABOUTME: Hier lebende clients spawnen oder auf nΣchsten gamestate warten?
  163.                             // - Hier gibt's noch keine arena, also besser warten...
  164.                         }
  165.                     }
  166.  
  167.                     log("Connected to '%s' as '%s'.\n", Network::info.var.server_name, ca.newName);
  168.  
  169.                     return true;
  170.                 }else if(answer->data[1] == PACKET_TYPE_CONNECTION_REQUEST_DECLINED){
  171.                     //log("Connection request declined by server. Reason:\n");
  172.                     connectionRequestDeclinedPacket_t cd;
  173.                     PacketHandler::unwrapAndFreePacket(answer, &cd, sizeof(cd));
  174.  
  175.                     error("(in Client::connect()): Connection request declined by server. Reason: %s\n\n", cd.reason);
  176.                     return false;
  177.                 }else{
  178.                     warn("(in Client::connect()): Received unexpected answer from server. Ignoring.\n\n");
  179.                     PacketHandler::freePacket(answer);
  180.                 }
  181.  
  182.             }
  183.         }while( answer != NULL );
  184.  
  185.     }
  186.  
  187.     log("Couldn't connect to %s:%i. Giving up.\n", Network::info.var.server_ip, Network::info.var.server_port);
  188.     return false;
  189. }
  190.  
  191. bool Client::disconnect(){
  192.     // send disconnect event
  193.     
  194.     disconnectPacket_t d;
  195.  
  196.     d.clientId = clientId;
  197.  
  198.     if(d.clientId == -1){
  199.         error("(in Client::disconnect()): Local clientId is -1.\n\n");
  200.         return false;
  201.     }
  202.     
  203.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_DISCONNECT, Network::server->ipAddress, &d, sizeof(d));
  204.     if(p == NULL){
  205.         error("(in Client::disconnect()): Couldn't alloc packet.\n\n");
  206.         return false;
  207.     }
  208.  
  209.     if( !Network::sendAndFreePacket(socket, p) ){
  210.         error("(in Client::disconnect()): Couldn't send packet.\n\n");
  211.         return false;
  212.     }
  213.  
  214.     log("Disconnect packet send.\n");
  215.  
  216.     if( vehicle != NULL ){
  217.         Game::unspawnVehicle(vehicle);
  218.     }
  219.  
  220.     Network::server->clients[d.clientId] = NULL;    // will be deleted later! (in shutdownClient())
  221.     this->clientId = -1;
  222.     
  223.     return true;
  224. }
  225.  
  226. int Client::getClientId(){
  227. //    for(int i=0;i<Network::server->maxClients;i++){
  228. //        if(Network::server->clients[i] != NULL && Network::server->clients[i] == this){
  229. //            return i;
  230. //        }
  231. //    }
  232. //
  233. //    return -1;
  234.     return clientId;
  235. }
  236.  
  237.  
  238. void Client::sendChatMessage(unsigned char mode, const char* message){
  239.     chatMessagePacket_t cm;
  240.     cm.clientId = this->clientId;
  241.     strncpy(cm.message, message, CON_MAX_STRING_LENGTH);
  242.     cm.mode = mode;
  243.  
  244.  
  245.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CHAT_MESSAGE, Network::server->ipAddress, &cm, sizeof(cm));
  246.     if(p == NULL){
  247.         error("(in Client::sendChatMessage()): Couldn't alloc packet.\n\n");
  248.         return;
  249.     }
  250.  
  251.     if( !Network::sendAndFreePacket(socket, p) ){
  252.         error("(in Client::sendChatMessage()): Couldn't send packet.\n\n");
  253.         return;
  254.     }
  255.     
  256. }
  257.  
  258. void Client::sendVoiceMessage(unsigned char mode, char messageId){
  259.     voiceMessagePacket_t vm;
  260.     vm.clientId = this->clientId;
  261.     vm.messageId = messageId;
  262.     vm.mode = mode;
  263.  
  264.  
  265.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_VOICE_MESSAGE, Network::server->ipAddress, &vm, sizeof(vm));
  266.     if(p == NULL){
  267.         error("(in Client::sendVoiceMessage()): Couldn't alloc packet.\n\n");
  268.         return;
  269.     }
  270.  
  271.     if( !Network::sendAndFreePacket(socket, p) ){
  272.         error("(in Client::sendVoiceMessage()): Couldn't send packet.\n\n");
  273.         return;
  274.     }
  275.     
  276. }
  277.  
  278. void Client::sendClientstate(){
  279.     clientstatePacket_t cs;
  280.  
  281.     cs = this->cs;
  282.     if( vehicle != NULL ){    // alive -> take vehicle vel, dir, up and let server approve values
  283.         vectorCopy3d(vehicle->pos, cs.pos);
  284.         vectorCopy3d(vehicle->vel_inp, cs.vel);    // send INPUT vel!!
  285.         vectorCopy3d(vehicle->dir, cs.dir);
  286.         vectorCopy3d(vehicle->up, cs.up);
  287.         cs.energy = (unsigned char)vehicle->energy;
  288.         cs.armor = (unsigned char)vehicle->armor;
  289.     }else{    // dead -> take cam pos (movement is unrestricted)
  290.         vectorCopy3d(Game::cam.pos, cs.pos);
  291.         vectorCopy3d(Game::cam.dir, cs.dir);
  292.         vectorCopy3d(Game::cam.up, cs.up);
  293.         vectorCopy3d(Game::cam.vel, cs.vel);
  294.         cs.energy = 0;
  295.         cs.armor = 0;
  296.     }
  297.  
  298.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENTSTATE, Network::server->ipAddress, &cs, sizeof(cs));
  299.     if(p == NULL){
  300.         error("(in Client::sendClientstate()): Couldn't alloc packet.\n\n");
  301.         return;
  302.     }
  303.  
  304.     if( !Network::sendAndFreePacket(socket, p) ){
  305.         error("(in Client::sendClientstate()): Couldn't send packet.\n\n");
  306.         return;
  307.     }
  308. }
  309.  
  310. void Client::sendClientSpawn(){
  311.     clientSpawnPacket_t cs;
  312.  
  313.     cs.clientId = this->clientId;
  314.     cs.ci = this->ci;
  315.     cs.cs = this->cs;
  316.  
  317.     // fill in the values we would like to have...
  318.     cs.ci.team = (char)Game::info.cvar.game_player_team->getVal();
  319.     cs.ci.vehicle = (char)Game::info.cvar.game_player_vehicle->getVal();
  320.     cs.ci.weapon1 = (char)Game::info.cvar.game_player_weapon1->getVal();
  321.     cs.ci.weapon2 = (char)Game::info.cvar.game_player_weapon2->getVal();
  322.     cs.ci.weapon3 = (char)Game::info.cvar.game_player_weapon3->getVal();
  323.     cs.ci.weapon4 = (char)Game::info.cvar.game_player_weapon4->getVal();
  324.  
  325.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_SPAWN, Network::server->ipAddress, &cs, sizeof(cs));
  326.     if(p == NULL){
  327.         error("(in Client::sendClientSpawn()): Couldn't alloc packet.\n\n");
  328.         return;
  329.     }
  330.  
  331.     if( !Network::sendAndFreePacket(socket, p) ){
  332.         error("(in Client::sendClientSpawn()): Couldn't send packet.\n\n");
  333.         return;
  334.     }
  335.  
  336. }
  337.  
  338. // send a suicide request
  339. void Client::sendClientKill(){
  340.     clientKillPacket_t ck;
  341.  
  342.     ck.killedClientId = this->clientId;
  343.     ck.killerClientId = this->clientId;
  344.     ck.weapon = GAME_WEAPON_NO_WEAPON;
  345.  
  346.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_CLIENT_KILL, Network::server->ipAddress, &ck, sizeof(ck));
  347.     if(p == NULL){
  348.         error("(in Client::sendClientKill()): Couldn't alloc packet.\n\n");
  349.         return;
  350.     }
  351.  
  352.     if( !Network::sendAndFreePacket(socket, p) ){
  353.         error("(in Client::sendClientKill()): Couldn't send packet.\n\n");
  354.         return;
  355.     }
  356.  
  357. }
  358.  
  359. void Client::sendShotSpawn(Shot* shot){
  360.     shotSpawnPacket_t ss;
  361.  
  362.     ss.clientId = this->clientId;
  363.     ss.weaponId = shot->weaponId;
  364.     ss.type = shot->type;
  365.     vectorCopy3d(shot->pos, ss.pos);
  366.     vectorCopy3d(shot->dir, ss.dir);
  367.     vectorCopy3d(shot->up, ss.up);
  368.     vectorCopy3d(shot->vel, ss.vel);
  369.  
  370.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_SHOT_SPAWN, Network::server->ipAddress, &ss, sizeof(ss));
  371.     if(p == NULL){
  372.         error("(in Client::sendShotSpawn()): Couldn't alloc packet.\n\n");
  373.         return;
  374.     }
  375.  
  376.     if( !Network::sendAndFreePacket(socket, p) ){
  377.         error("(in Client::sendShotSpawn()): Couldn't send packet.\n\n");
  378.         return;
  379.     }
  380.         
  381. }
  382.  
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393. void Client::sendPackets(){
  394.     unsigned long currentMillis = SDL_GetTicks();
  395.  
  396.     // clientstate stuff
  397.     if(!Game::info.var.clientGame){    // update cs on local server
  398.         if( vehicle != NULL ){    // alive -> take vehicle vel, dir, up and let server approve values
  399.             vectorCopy3d(vehicle->pos, cs.pos);
  400.             vectorCopy3d(vehicle->vel_inp, cs.vel);
  401.             vectorCopy3d(vehicle->dir, cs.dir);
  402.             vectorCopy3d(vehicle->up, cs.up);
  403.             cs.armor = (unsigned char)vehicle->armor;
  404.             cs.energy = (unsigned char)vehicle->energy;
  405.  
  406.         }else{    // dead -> take cam pos (movement is unrestricted)
  407.             vectorCopy3d(Game::cam.pos, cs.pos);
  408.             vectorCopy3d(Game::cam.dir, cs.dir);
  409.             vectorCopy3d(Game::cam.up, cs.up);
  410.             vectorCopy3d(Game::cam.vel, cs.vel);
  411.         }
  412.     }
  413.  
  414.     // send cs if necessary (i.e. time has come and we're on a remote server)
  415.     if(Game::info.var.clientGame && currentMillis - lastClientstateMillis > (unsigned long)Network::info.var.client_clientstateInterval){
  416. //        log("Sending clientstate...\n");
  417.         sendClientstate();
  418.  
  419.         lastClientstateMillis = currentMillis;
  420.     }
  421.  
  422.     // send spawn request if necessary
  423.     if( nextSpawnMillis < currentMillis ){
  424.         if( //Game::info.cvar.game_player_team->getVal() != Game::info.var.player_team // wants to change team
  425.             Game::info.cvar.game_player_team->getVal() != GAME_TEAM_SPECTATORS && Game::info.var.player_team == GAME_TEAM_SPECTATORS // wants to join game
  426.             || (Game::info.var.player_team != GAME_TEAM_SPECTATORS && vehicle == NULL) // or regular respawn (playing and dead)
  427.             ){    
  428.             sendClientSpawn();
  429.             nextSpawnMillis = SDL_GetTicks() + Game::info.var.ghostTime;    // schedule next try (if that one fails...)
  430.         }
  431.     }
  432. }
  433.  
  434. void Client::receivePackets(){
  435.     // if we are connected to a remote server check if server is still alive
  436.     if( Game::info.var.clientGame ){
  437.         unsigned long currentMillis = SDL_GetTicks();
  438.         if( ((currentMillis - lastPingMillis)/1000) % 5 > (unsigned long)5000 ){    // connection interrupted
  439.             log("Connection to server interrupted.\n");
  440.         }
  441.         if(currentMillis - lastPingMillis > (unsigned long)Network::info.var.client_maxServerIdleTime){    // disconnect
  442.             error("(in Client::receivePackets()): Server is not responding. Disconnecting.\n\n");
  443. //            this->clientId = -1;
  444.             Game::shutdown();
  445.             Gui::mainMenu->open();
  446.         }
  447.     }
  448.  
  449.     // receive packets
  450.     UDPpacket** packets = SDLNet_AllocPacketV(NETWORK_MAX_PACKETS_PER_FRAME, NETWORK_MAX_PACKET_SIZE);
  451.     if(packets == NULL){
  452.         error("(in Client::receivePackets()): Unable to alloc packets.\n\n");
  453.         return;
  454.     }
  455.  
  456.     int numReceived = SDLNet_UDP_RecvV(socket, packets);
  457.     if(numReceived == -1){
  458.         error("(in Client::receivePackets()): SDLNet_UDP_RecvV failed: %s.\n\n", SDLNet_GetError());
  459.         return;
  460.     }
  461.  
  462.     for(int i=0;i<numReceived;i++){
  463.  
  464.         if(packets[i]->data[0] != NETWORK_FWP_PACKET_ID){
  465.             warn("(in Client::receivePackets()): Received unknown packet.\n\n");
  466.             continue;
  467.         }
  468.         handlePacket(packets[i]);
  469.     }
  470.  
  471.     SDLNet_FreePacketV(packets);
  472. }
  473.  
  474.  
  475. void Client::handlePacket(UDPpacket* packet){
  476. //    printf("client::handlePacket(): received packet of type %i.\n", packet->data[1]);
  477.  
  478.     switch(packet->data[1]){
  479.         case PACKET_TYPE_PING:
  480. //            log("Client::handlePacket(): Received ping packet.\n");
  481.             handlePing(packet);
  482.             break;
  483.  
  484.         case PACKET_TYPE_DISCONNECT:
  485. //            log("Client::handlePacket(): Received disconnect packet.\n");
  486.             handleDisconnect(packet);
  487.             break;
  488.  
  489.         case PACKET_TYPE_CLIENT_CONNECTED:
  490. //            log("Client::handlePacket(): Received clientConnected packet.\n");
  491.             handleClientConnected(packet);
  492.             break;
  493.  
  494.         case PACKET_TYPE_CLIENT_DISCONNECTED:
  495. //            log("Client::handlePacket(): Received clientDisconnected packet.\n");
  496.             handleClientDisconnected(packet);
  497.             break;
  498.  
  499.         case PACKET_TYPE_CHAT_MESSAGE:
  500. //            log("Client::handlePacket(): Received chatMessage packet.\n");
  501.             handleChatMessage(packet);
  502.             break;
  503.  
  504.         case PACKET_TYPE_VOICE_MESSAGE:
  505. //            log("Client::handlePacket(): Received voiceMessage packet.\n");
  506.             handleVoiceMessage(packet);
  507.             break;
  508.  
  509.         case PACKET_TYPE_PLAYERINFO:
  510. //            log("Client::handlePacket(): Received playerinfo packet.\n");
  511.             handlePlayerinfo(packet);
  512.             break;
  513.  
  514.         case PACKET_TYPE_GAMESTATE:
  515. //            log("Client::handlePacket(): Received gamestate packet.\n");
  516.             handleGamestate(packet);
  517.             break;
  518.         
  519.         case PACKET_TYPE_CLIENT_SPAWN:
  520. //            log("Client::handlePacket(): Received clientSpawn packet.\n");
  521.             handleClientSpawn(packet);
  522.             break;
  523.  
  524.         case PACKET_TYPE_CLIENT_HURT:
  525. //            log("Client::handlePacket(): Received clientHurt packet.\n");
  526.             handleClientHurt(packet);
  527.             break;
  528.  
  529.         case PACKET_TYPE_CLIENT_KILL:
  530. //            log("Client::handlePacket(): Received clientKill packet.\n");
  531.             handleClientKill(packet);
  532.             break;
  533.  
  534.         case PACKET_TYPE_SHOT_SPAWN:
  535. //            log("Client::handlePacket(): Received shotSpawn packet.\n");
  536.             handleShotSpawn(packet);
  537.             break;
  538.  
  539.         case PACKET_TYPE_ARENA_CHANGE:
  540. //            log("Client::handlePacket(): Received arenaChange packet.\n");
  541.             handleArenaChange(packet);
  542.             break;
  543.  
  544.         default:
  545.             warn("Client::handlePacket(): Received packet of unknown type. Ignoring.\n");
  546.             break;
  547.     } // switch
  548.  
  549.  
  550. }
  551.  
  552.  
  553. void Client::emptyPacketQueue(){
  554.     int numLoops = 0;
  555.     int numReceived = 0;
  556.  
  557.     // receive packets
  558.     do{
  559.         UDPpacket** packets = SDLNet_AllocPacketV(NETWORK_MAX_PACKETS_PER_FRAME, NETWORK_MAX_PACKET_SIZE);
  560.         if(packets == NULL){
  561.             error("(in Client::receivePackets()): Unable to alloc packets.\n\n");
  562.             return;
  563.         }
  564.  
  565.         numReceived = SDLNet_UDP_RecvV(socket, packets);
  566.         if(numReceived == -1){
  567.             error("(in Client::emptyPacketQueue()): SDLNet_UDP_RecvV failed: %s.\n\n", SDLNet_GetError());
  568.             return;
  569.         }
  570.         SDLNet_FreePacketV(packets);
  571.  
  572.         numLoops++;
  573.     }while(numReceived > 0 && numLoops < 10);
  574.  
  575. }
  576.  
  577.  
  578.  
  579. void Client::handlePing(UDPpacket* packet){
  580.     pingPacket_t pp;
  581.  
  582.     if( !PacketHandler::unwrapPacket(packet, &pp, sizeof(pp)) ){
  583.         error("(Client::handlePing()): Couldn't unwrap packet.\n\n");
  584.         return;
  585.     }
  586.  
  587.     if(pp.protocolVersion != Network::info.var.protocolVersion){
  588.         warn("(in Client::handlePing()): Received ping packet with invalid protocol version. Ignoring\n\n");
  589.         return;
  590.     }
  591.  
  592.     this->lastPingMillis = SDL_GetTicks(); // remember time
  593.     // fill in clientID and send it back to server
  594.     pp.clientId = this->clientId;
  595.     UDPpacket* p = PacketHandler::wrapPacket(PACKET_TYPE_PING, Network::server->ipAddress, &pp, sizeof(pp));
  596.     if(p == NULL){
  597.         error("(in Client::handlePing()): Couldn't alloc packet.\n\n");
  598.         return;
  599.     }
  600.  
  601.     if( !Network::sendAndFreePacket(socket, p) ){
  602.         error("(in Client::handlePing()): Couldn't send packet.\n\n");
  603.         SDLNet_FreePacket(p);
  604.         return;
  605.     }
  606.     
  607. }
  608.  
  609. void Client::handleDisconnect(UDPpacket* packet){
  610.     //log("Server disconnected.\n");
  611.     disconnectPacket_t d;
  612.     if( !PacketHandler::unwrapPacket(packet, &d, sizeof(d)) ){
  613.         error("(Client::handleDisconnect()): Couldn't unwrap packet.\n\n");
  614.         return;
  615.     }
  616.  
  617.     error("(in Client::handleDisconnect()): Server disconnected. Reason: %s\n", d.reason);
  618.     Network::server->clients[this->clientId] = NULL;
  619.     this->clientId = -1;
  620.     Game::shutdown();
  621.     Gui::mainMenu->open();
  622. }
  623.  
  624. void Client::handleClientConnected(UDPpacket* packet){
  625.     clientConnectedPacket_t cc;
  626.     if( !PacketHandler::unwrapPacket(packet, &cc, sizeof(cc)) ){
  627.         error("(Client::handleClientConnected()): Couldn't unwrap packet.\n\n");
  628.         return;
  629.     }
  630.     
  631.     if(cc.clientId < 0 || cc.clientId >= Network::server->si.maxClients){
  632.         warn("(in Client::handleClientConnected()): ClientId of new client out of bounds. Ignoring.\n\n.");
  633.         return;
  634.     }
  635.  
  636.     if( Network::server->clients[cc.clientId] != NULL ){
  637.         warn("(in Client::handleClientConnected()): ClientId of new client already in use. Overwriting.\n\n.");
  638.         delete Network::server->clients[cc.clientId];
  639.     }
  640.  
  641.     Client* c = new Client();
  642.     Network::server->clients[cc.clientId] = c;
  643.     c->ci = cc.ci;
  644.  
  645.     log("'%s' connected.\n", c->ci.name);
  646. }
  647.  
  648. void Client::handleClientDisconnected(UDPpacket* packet){
  649.     clientDisconnectedPacket_t cd;
  650.     if( !PacketHandler::unwrapPacket(packet, &cd, sizeof(cd)) ){
  651.         error("(Client::handleClientDisconnected()): Couldn't unwrap packet.\n\n");
  652.         return;
  653.     }
  654.     
  655.     if(cd.clientId < 0 || cd.clientId >= Network::server->si.maxClients){
  656.         warn("(in Client::handleClientDisconnected()): ClientId of client out of bounds. Ignoring.\n\n.");
  657.         return;
  658.     }
  659.  
  660.     Client* c = Network::server->clients[cd.clientId];
  661.     if( c == NULL ){
  662.         warn("(in Client::handleClientDisconnected()): ClientId of client already free. Ignoring.\n\n.");
  663.         return;
  664.     }
  665.  
  666.     if( c->vehicle != NULL ){
  667.         Game::unspawnVehicle(c->vehicle);
  668.     }
  669.  
  670.     log("'%s' disconnected. Reason: %s.\n", c->ci.name, cd.reason);
  671.  
  672.     Network::server->removeClient(c);
  673. }
  674.  
  675. void Client::handleChatMessage(UDPpacket* packet){
  676.     //log("Server disconnected.\n");
  677.  
  678.     chatMessagePacket_t cm;
  679.     if( !PacketHandler::unwrapPacket(packet, &cm, sizeof(cm)) ){
  680.         error("(in Client::handleChatMessage()): Couldn't unwrap packet.\n\n");
  681.         return;
  682.     }
  683.     
  684.     if( cm.mode == GAME_CHAT_MODE_SERVER ){
  685.         Gui::hud->messagebox->addChatMessage(NULL, &cm);
  686.         return;
  687.     }
  688.  
  689.     if(cm.clientId < 0 || cm.clientId >= Network::server->si.maxClients){
  690.         warn("(in Client::handleChatMessage()): ClientId out of bounds.\n\n");
  691.         return;
  692.     }
  693.  
  694.     Client* c = Network::server->clients[cm.clientId];
  695.     if(c != NULL){
  696.         Gui::hud->messagebox->addChatMessage(c, &cm);
  697.     }else{
  698.         warn("(in Client::handleChatMessage()): Received chat message from unknown client.\n\n");
  699.     }
  700. }
  701.  
  702. void Client::handleVoiceMessage(UDPpacket* packet){
  703.     //log("Server disconnected.\n");
  704.  
  705.     voiceMessagePacket_t vm;
  706.     if( !PacketHandler::unwrapPacket(packet, &vm, sizeof(vm)) ){
  707.         error("(in Client::handleVoiceMessage()): Couldn't unwrap packet.\n\n");
  708.         return;
  709.     }
  710.     
  711.     if(vm.clientId < 0 || vm.clientId >= Network::server->si.maxClients){
  712.         warn("(in Client::handleVoiceMessage()): ClientId out of bounds.\n\n");
  713.         return;
  714.     }
  715.  
  716.     if( vm.messageId < 0 || vm.messageId >= GAME_NUM_VOICE_MESSAGES ){
  717.         warn("(in Client::handleVoiceMessage()): MessageId out of bounds.\n\n");
  718.         return;
  719.     }
  720.  
  721.     Client* c = Network::server->clients[vm.clientId];
  722.     if(c != NULL){
  723.         if( Game::info.var.allowVoiceMessages >= 1 ){
  724.             chatMessagePacket_t cm;
  725.             cm.clientId = vm.clientId;
  726.             cm.mode = vm.mode;
  727.             sprintf(cm.message, "[voicemessage '%s']", Game::getVoiceMessageName(vm.messageId));
  728.  
  729.             Gui::hud->messagebox->addChatMessage(c, &cm);
  730.         }
  731.  
  732.         if(Sound::info.var.enabled && Sound::info.var.playSamples 
  733.             && Game::info.var.allowVoiceMessages >= 2 && Game::preloadedGameMedia.voiceMessages[vm.messageId] != NULL ){
  734.             Sound::playSample(SOUND_RADIO_CHANNEL, Game::preloadedGameMedia.voiceMessages[vm.messageId]);
  735.         }
  736.     }else{
  737.         warn("(in Client::handleVoiceMessage()): Received voice message from unknown client.\n\n");
  738.     }
  739. }
  740.  
  741.  
  742. void Client::handlePlayerinfo(UDPpacket* packet){
  743.     playerinfoPacket_t pi;
  744.     if( !PacketHandler::unwrapPacket(packet, &pi, sizeof(pi)) ){
  745.         error("(in Client::handlePlayerinfo()): Couldn't unwrap packet.\n\n");
  746.         return;
  747.     }
  748.  
  749.     for(int j=0;j<Network::server->si.maxClients;j++){
  750.         if(pi.clientIds[j] != -1){
  751.             Client* c;
  752.             c = Network::server->clients[j];
  753.             if( c == NULL ){
  754.                 warn("(in Client::handlePlayerinfo()): Slot %i is in playerinfo but not connected. Adding new client...\n\n", j);
  755.                 //log("(Maybe I just missed the connection event. )\n");
  756.                 //continue;
  757.                 c = new Client();
  758.                 Network::server->clients[j] = c;
  759.             }
  760.                 
  761.             c->clientId = j;    // THINKABOUTME: sowie so schon klar...
  762.             c->ci = pi.ci[j];
  763.         }else if(pi.clientIds[j] == -1 && Network::server->clients[j] != NULL){    // missed disconnect?
  764.             warn("(in Client::handlePlayerinfo()): Slot %i is empty in playerinfo but in shadow server. Removing client...\n\n", j);
  765.             Network::server->removeClient(Network::server->clients[j]);
  766.         }
  767.     }
  768.  
  769.  
  770. }
  771.  
  772.  
  773. void Client::handleGamestate(UDPpacket* packet){
  774. //    log("Hab gamestate gekriegt!\n");
  775.  
  776.     gamestatePacket_t gs;
  777.     if( !PacketHandler::unwrapPacket(packet, &gs, sizeof(gs)) ){
  778.         error("(in Client::handleGamestate()): Couldn't unwrap packet.\n\n");
  779.         return;
  780.     }
  781.  
  782.  
  783.     for(int j=0;j<Network::server->si.maxClients;j++){
  784.         if(gs.clientIds[j] != -1){
  785.             Client* c;
  786.             c = Network::server->clients[j];
  787.             if( c == NULL ){
  788.                 warn("(in Client::handleGamestate()): Slot %i is in gamestate but not connected. Adding new client...\n\n", j);
  789.                 c = new Client();
  790.                 c->setName("???");    // will be changed with next playerinfo
  791.                 Network::server->clients[j] = c;
  792.             }
  793.  
  794.             c->cs = gs.cs[j];
  795.  
  796.             if( c->ci.team != GAME_TEAM_SPECTATORS && c->cs.armor > 0 && c->vehicle == NULL ){    // missed spawn event?
  797. //                warn("(in Client::handleGamestate()): Slot %i is alive in gamestate but not on shadow server. Spawning...\n\n", j);
  798.                 Game::spawnVehicle(c);
  799.             }
  800.             if( c->ci.team != GAME_TEAM_SPECTATORS && c->cs.armor == 0 && c->vehicle != NULL ){    // missed kill event?
  801. //                warn("(in Client::handleGamestate()): Slot %i is dead in gamestate but not on shadow server. Unspawning...\n\n", j);
  802.                 Game::unspawnVehicle(c->vehicle);
  803.             }
  804.  
  805.             if( c->vehicle != NULL ){
  806.                 if( c != this ){    // keep local stuff to smoothen moves
  807.                     vectorCopy3d(c->cs.pos, c->vehicle->pos);
  808.                     vectorCopy3d(c->cs.dir, c->vehicle->dir);
  809.                     vectorCopy3d(c->cs.up, c->vehicle->up);
  810.                     vectorCopy3d(c->cs.vel, c->vehicle->vel_inp);
  811.  
  812.                     c->vehicle->energy = c->cs.energy;    // energy is handled on client
  813.                 }
  814.                 c->vehicle->armor = c->cs.armor;
  815.             }
  816.             
  817.         }else if(gs.clientIds[j] == -1 && Network::server->clients[j] != NULL){    // missed disconnect?
  818.             warn("(in Client::handleGamestate()): Slot %i is empty in gamestate but in shadow server. Removing client '%s'...\n\n", j, Network::server->clients[j]->ci.name);
  819.             Network::server->removeClient(Network::server->clients[j]);
  820.         }
  821.     }
  822.  
  823. }
  824.  
  825. void Client::handleClientSpawn(UDPpacket* packet){
  826.     clientSpawnPacket_t cs;
  827.  
  828.     if( !PacketHandler::unwrapPacket(packet, &cs, sizeof(cs)) ){
  829.         error("(in Client::handleClientSpawn()): Couldn't unwrap packet.\n\n");
  830.         return;
  831.     }
  832.  
  833.     Client* c = Network::server->clients[cs.clientId];
  834.     if( c == NULL ){
  835.             warn("(in Client::handleClientSpawn()): Slot %i is spawning but not connected. Adding new client...\n\n", cs.clientId);
  836.             c = new Client();
  837.             Network::server->clients[cs.clientId] = c;
  838.     }
  839.  
  840.     if( c->ci.team != cs.ci.team || cs.ci.team == GAME_TEAM_SPECTATORS ){    // log change team
  841.         log("%s joined %s.\n", cs.ci.name, Game::getTeamName(cs.ci.team) );
  842.     }
  843.  
  844.     c->ci = cs.ci;
  845.     c->cs = cs.cs;
  846.  
  847.     if( c == this ){
  848.         // UPDATE GAME CVARS!!!!
  849.         Game::info.var.player_team = c->ci.team;
  850.         Game::info.cvar.game_player_team->setVal(c->ci.team);    // THINKABOUTME: to avoid respawns caused by changing teams
  851.         Game::info.var.player_vehicle = c->ci.vehicle;
  852.         Game::info.var.player_weapon1 = c->ci.weapon1;
  853.         Game::info.var.player_weapon2 = c->ci.weapon2;
  854.         Game::info.var.player_weapon3 = c->ci.weapon3;
  855.         Game::info.var.player_weapon4 = c->ci.weapon4;
  856.     }
  857.  
  858.     if( c->vehicle != NULL ){
  859.         Game::unspawnVehicle(c->vehicle);
  860.     }
  861.     Game::spawnVehicle(c);
  862.  
  863.     if( c->ci.team != GAME_TEAM_SPECTATORS ){
  864. //        log("%s has spawned for %s with a %s.\n", c->ci.name, Game::getTeamName(c->ci.team), Game::getVehicleName(c->ci.vehicle) );
  865.     }
  866. }
  867.  
  868. void Client::handleClientHurt(UDPpacket* packet){
  869.     clientHurtPacket_t ch;
  870.  
  871.     if( !PacketHandler::unwrapPacket(packet, &ch, sizeof(ch)) ){
  872.         error("(in Client::handleClientHurt()): Couldn't unwrap packet.\n\n");
  873.         return;
  874.     }
  875.  
  876.     Client* hurtClient = Network::server->clients[ch.hurtClientId];
  877.     Client* hurterClient = Network::server->clients[ch.hurterClientId];
  878.  
  879.     if( hurtClient == NULL ){
  880.         warn("(in Client::handleClientHurt()): Received clientHurt packet with invalid hurtClientId. Ignoring.\n\n");
  881.         return;
  882.     }
  883.     if( hurterClient == NULL ){    // May have disconnected
  884.         warn("(in Client::handleClientHurt()): Received clientHill packet with invalid hurterClientId.\n\n");
  885. //        return;
  886.     }
  887.  
  888.     if( hurtClient->vehicle == NULL ){
  889.         warn("(in Client::handleClientHurt()): Received clientHurt packet with hurtClient that is already dead. Ignoring.\n\n");
  890.         return;
  891.     }
  892.  
  893.     hurtClient->vehicle->takeDamage(ch.amount);
  894. }
  895.  
  896. void Client::handleClientKill(UDPpacket* packet){
  897.     clientKillPacket_t ck;
  898.  
  899.     if( !PacketHandler::unwrapPacket(packet, &ck, sizeof(ck)) ){
  900.         error("(in Client::handleClientKill()): Couldn't unwrap packet.\n\n");
  901.         return;
  902.     }
  903.  
  904.     Client* killedClient = Network::server->clients[ck.killedClientId];
  905.     Client* killerClient = Network::server->clients[ck.killerClientId];
  906.  
  907.     if( killedClient == NULL ){
  908.         warn("(in Client::handleClientKill()): Received client kill packet with invalid killedClientId. Ignoring.\n\n");
  909.         return;
  910.     }
  911.     if( killerClient == NULL ){    // May have disconnected
  912.         warn("(in Client::handleClientKill()): Received client kill packet with invalid killerClientId. Ignoring.\n\n");
  913.         //return;
  914.     }
  915.  
  916.     if( killedClient->vehicle == NULL ){
  917.         warn("(in Client::handleClientKill()): Received client kill packet with killedClient that is already dead. Ignoring.\n\n");
  918.         return;
  919.     }
  920.  
  921.     Game::killClient(killedClient, killerClient, ck.weapon);
  922. }
  923.  
  924. void Client::handleShotSpawn(UDPpacket* packet){
  925.     shotSpawnPacket_t ss;
  926.  
  927.     if( !PacketHandler::unwrapPacket(packet, &ss, sizeof(ss)) ){
  928.         error("(in Client::handleShotSpawn()): Couldn't unwrap packet.\n\n");
  929.         return;
  930.     }
  931.  
  932.     Game::spawnShot(&ss);
  933.     
  934. }
  935.  
  936. void Client::handleArenaChange(UDPpacket* packet){
  937.     arenaChangePacket_t ac;
  938.  
  939.     if( !PacketHandler::unwrapPacket(packet, &ac, sizeof(ac)) ){
  940.         error("(in Client::handleArenaChange()): Couldn't unwrap packet.\n\n");
  941.         return;
  942.     }
  943.  
  944.     Game::info.cvar.game_arena->setValStr(ac.newArena);
  945.     Game::info.cvar.game_arena->updateVar();
  946.  
  947.     Gui::loadingMenu->open();
  948.     Gui::loadingMenu->updateStatusBar("changing arena");
  949.     Gui::loadingMenu->updateHeading("changing arena");
  950.     Gui::loadingMenu->updateSubHeading(Game::getModeName(Game::info.var.mode));
  951.  
  952.     if( !Game::changeArena() ){
  953.         error("(in Client::handeArenaChange()): Game::changeArena() failed.\n\n");
  954.         Game::shutdown();
  955.         Gui::mainMenu->open();
  956.     }
  957.     Network::server->resetClients();
  958.     emptyPacketQueue();
  959.  
  960.     Gui::loadingMenu->updateStatusBar("awaiting GS");
  961.  
  962.     // wait for answer
  963.     unsigned long startWaitingMillis = SDL_GetTicks();
  964.  
  965.     do{
  966.         log("Awaiting gamestate...\n");
  967.         UDPpacket** packets = SDLNet_AllocPacketV(NETWORK_MAX_PACKETS_PER_FRAME, NETWORK_MAX_PACKET_SIZE);
  968.         if(packets == NULL){
  969.             error("(in Client::handleArenaChange()): Unable to alloc packets.\n\n");
  970.             return;
  971.         }
  972.  
  973.         int numReceived = SDLNet_UDP_RecvV(socket, packets);
  974.         if(numReceived == -1){
  975.             error("(in Client::handleArenaChange()): SDLNet_UDP_RecvV failed: %s.\n\n", SDLNet_GetError());
  976.             return;
  977.         }
  978.  
  979.         for(int i=0;i<numReceived;i++){
  980.             if(packets[i]->data[0] != NETWORK_FWP_PACKET_ID){
  981.                 warn("(in Client::handleArenaChange()): Received unknown packet.\n\n");
  982.                 continue;
  983.             }
  984.  
  985.             if(packets[i]->data[1] == PACKET_TYPE_GAMESTATE){
  986.                 handleGamestate(packets[i]);
  987.                 SDLNet_FreePacketV(packets);
  988. //                emptyPacketQueue();
  989.                 Gui::loadingMenu->close();
  990.                 log("Gamestate received. Re-entering Mainloop...\n");
  991.                 Game::mainLoop();
  992.                 return;    // never reached???
  993.             }
  994.         }
  995.         SDLNet_FreePacketV(packets);
  996.  
  997.         SDL_Delay(1000);
  998.     }while( SDL_GetTicks() < startWaitingMillis + Network::info.var.client_maxServerIdleTime );
  999.  
  1000.     Gui::loadingMenu->close();
  1001.     error("(in Client::handleArenaChange()): Server is not responding. Disconnecting.\n\n");
  1002.     Game::shutdown();
  1003.     Gui::mainMenu->open();
  1004. }
  1005.  
  1006.