Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jun 1, 2008, 3:54:20 PM (16 years ago)
Author:
rgrieder
Message:
  • @everyone: Do not create a branch until I've added the svn:eol-style property correctly. Otherwise this would cost me another 4 hours or so when we want to merge back.
  • merged network branch back to trunk
  • I had to omit the changes from last evening concerning the line endings
  • might not work yet because of the line endings
  • @beni: script branch is the only branch still open. you probably will have to apply a patch because of inconsistent new lines
File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/network/ConnectionManager.cc

    r1360 r1502  
    4444#include "core/CoreIncludes.h"
    4545#include "core/BaseObject.h"
     46#include "objects/SpaceShip.h"
    4647#include "util/Math.h"
    47 #include "objects/SpaceShip.h"
     48#include "util/Sleep.h"
    4849#include "ClientInformation.h"
    4950#include "ConnectionManager.h"
     
    6566 
    6667  ConnectionManager::ConnectionManager():receiverThread_(0){}
     68  boost::recursive_mutex ConnectionManager::enet_mutex_;
    6769 
    6870  ConnectionManager::ConnectionManager(ClientInformation *head) : receiverThread_(0) {
     
    7274    head_ = head;
    7375  }
     76 
     77  ConnectionManager::ConnectionManager(ClientInformation *head, int port){
     78    quit=false;
     79    bindAddress.host = ENET_HOST_ANY;
     80    bindAddress.port = port;
     81    head_ = head;
     82  }
    7483
    7584  ConnectionManager::ConnectionManager(int port, std::string address, ClientInformation *head) :receiverThread_(0) {
     
    8796  }
    8897
    89   ENetPacket *ConnectionManager::getPacket(ENetAddress &address) {
     98  /*ENetPacket *ConnectionManager::getPacket(ENetAddress &address) {
    9099    if(!buffer.isEmpty())
    91100      return buffer.pop(address);
    92101    else
    93102      return NULL;
    94   }
     103  }*/
    95104/**
    96105This function only pops the first element in PacketBuffer (first in first out)
    97106used by processQueue in Server.cc
    98107*/
    99   ENetPacket *ConnectionManager::getPacket(int &clientID) {
     108  /*ENetPacket *ConnectionManager::getPacket(int &clientID) {
    100109    ENetAddress address;
    101110    ENetPacket *packet=getPacket(address);
     
    105114    clientID=temp->getID();
    106115    return packet;
     116  }*/
     117 
     118  ENetEvent *ConnectionManager::getEvent(){
     119    if(!buffer.isEmpty())
     120      return buffer.pop();
     121    else
     122      return NULL;
    107123  }
    108124
     
    129145    if(!temp)
    130146      return false;
     147    boost::recursive_mutex::scoped_lock lock(enet_mutex_);
    131148    if(enet_peer_send(peer, (enet_uint8)temp->getID() , packet)!=0)
    132149      return false;
     
    136153  bool ConnectionManager::addPacket(ENetPacket *packet, int clientID) {
    137154    ClientInformation *temp = head_->findClient(clientID);
    138     if(!temp)
    139       return false;
    140     if(enet_peer_send(temp->getPeer(), (enet_uint8)clientID, packet)!=0)
    141       return false;
     155    if(!temp){
     156      COUT(3) << "C.Man: addPacket findClient failed" << std::endl;
     157      return false;
     158    }
     159    boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     160    if(enet_peer_send(temp->getPeer(), 0, packet)!=0){
     161      COUT(3) << "C.Man: addPacket enet_peer_send failed" << std::endl;
     162      return false;
     163    }
    142164    return true;
    143165  }
    144166
    145167  bool ConnectionManager::addPacketAll(ENetPacket *packet) {
     168    boost::recursive_mutex::scoped_lock lock(enet_mutex_);
    146169    for(ClientInformation *i=head_->next(); i!=0; i=i->next()){
    147170      if(enet_peer_send(i->getPeer(), (enet_uint8)i->getID(), packet)!=0)
     
    151174  }
    152175
    153   bool ConnectionManager::sendPackets(ENetEvent *event) {
     176  // we actually dont need that function, because host_service does that for us
     177  bool ConnectionManager::sendPackets() {
    154178    if(server==NULL)
    155179      return false;
    156     if(enet_host_service(server, event, NETWORK_SEND_WAIT)>=0)
    157       return true;
    158     else
    159       return false;
    160   }
    161 
    162   bool ConnectionManager::sendPackets() {
    163     ENetEvent event;
    164     if(server==NULL)
    165       return false;
    166     if(enet_host_service(server, &event, NETWORK_SEND_WAIT)>=0)
    167       return true;
    168     else
    169       return false;
     180    boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     181    enet_host_flush(server);
     182    lock.unlock();
     183    return true;
    170184  }
    171185
    172186  void ConnectionManager::receiverThread() {
    173187    // what about some error-handling here ?
    174     enet_initialize();
     188    ENetEvent *event;
    175189    atexit(enet_deinitialize);
    176     ENetEvent *event = new ENetEvent;
    177     server = enet_host_create(&bindAddress, NETWORK_MAX_CONNECTIONS, 0, 0);
     190    { //scope of the mutex
     191      boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     192      enet_initialize();
     193      server = enet_host_create(&bindAddress, NETWORK_MAX_CONNECTIONS, 0, 0);
     194      lock.unlock();
     195    }
    178196    if(server==NULL){
    179197      // add some error handling here ==========================
     
    182200    }
    183201
     202    event = new ENetEvent;
    184203    while(!quit){
    185       if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
    186         // we should never reach this point
    187         quit=true;
    188         // add some error handling here ========================
     204      { //mutex scope
     205        boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     206        if(enet_host_service(server, event, NETWORK_WAIT_TIMEOUT)<0){
     207          // we should never reach this point
     208          quit=true;
     209          continue;
     210          // add some error handling here ========================
     211        }
     212        lock.unlock();
    189213      }
    190214      switch(event->type){
    191215        // log handling ================
    192216        case ENET_EVENT_TYPE_CONNECT:
    193           addClient(event);
     217          COUT(3) << "adding event_type_connect to queue" << std::endl;
     218        case ENET_EVENT_TYPE_DISCONNECT:
     219          //addClient(event);
    194220          //this is a workaround to ensure thread safety
    195           COUT(5) << "Con.Man: connection event has occured" << std::endl;
    196           break;
     221          //COUT(5) << "Con.Man: connection event has occured" << std::endl;
     222          //break;
    197223        case ENET_EVENT_TYPE_RECEIVE:
    198224          //std::cout << "received data" << std::endl;
    199225          COUT(5) << "Con.Man: receive event has occured" << std::endl;
    200226          // only add, if client has connected yet and not been disconnected
    201           if(head_->findClient(&event->peer->address))
     227          //if(head_->findClient(&event->peer->address))
    202228            processData(event);
    203           else
    204             COUT(3) << "received a packet from a client we don't know" << std::endl;
     229            event = new ENetEvent;
     230//           else
     231//             COUT(3) << "received a packet from a client we don't know" << std::endl;
    205232          break;
    206         case ENET_EVENT_TYPE_DISCONNECT:
    207           clientDisconnect(event->peer);
     233        //case ENET_EVENT_TYPE_DISCONNECT:
     234          //clientDisconnect(event->peer);
     235          //break;
     236        case ENET_EVENT_TYPE_NONE:
     237          //receiverThread_->yield();
     238          usleep(1000);
    208239          break;
    209         case ENET_EVENT_TYPE_NONE:
    210           receiverThread_->yield();
    211           break;
    212240      }
    213241//       usleep(100);
    214       receiverThread_->yield(); //TODO: find apropriate
     242      //receiverThread_->yield(); //TODO: find apropriate
    215243    }
    216244    disconnectClients();
    217245    // if we're finishied, destroy server
    218     enet_host_destroy(server);
     246    {
     247      boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     248      enet_host_destroy(server);
     249      lock.unlock();
     250    }
    219251  }
    220252 
     
    226258    ClientInformation *temp = head_->next();
    227259    while(temp!=0){
    228       enet_peer_disconnect(temp->getPeer(), 0);
     260      {
     261        boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     262        enet_peer_disconnect(temp->getPeer(), 0);
     263        lock.unlock();
     264      }
    229265      temp = temp->next();
    230266    }
    231267    //bugfix: might be the reason why server crashes when clients disconnects
    232     //temp = temp->next();
    233268    temp = head_->next();
    234     while( temp!=0 && enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT) > 0){
     269    boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     270    while( temp!=0 && enet_host_service(server, &event, NETWORK_WAIT_TIMEOUT) >= 0){
    235271      switch (event.type)
    236272      {
     
    258294  }
    259295
    260   bool ConnectionManager::clientDisconnect(ENetPeer *peer) {
    261     COUT(4) << "removing client from list" << std::endl;
    262     return removeClient(head_->findClient(&(peer->address))->getID());
    263   }
    264 /**
    265 This function adds a client that connects to the clientlist of the server
    266 NOTE: if you change this, don't forget to change the test function
    267 addClientTest in diffTest.cc since addClient is not good for testing because of syncClassid
    268 */
    269   bool ConnectionManager::addClient(ENetEvent *event) {
    270     ClientInformation *temp = head_->insertBack(new ClientInformation);
    271     if(!temp){
    272       COUT(2) << "Conn.Man. could not add client" << std::endl;
    273       return false;
    274     }
    275     if(temp->prev()->getHead()) { //not good if you use anything else than insertBack
    276       temp->prev()->setID(0); //bugfix: not necessary but usefull
    277       temp->setID(1);
    278     }
    279     else
    280       temp->setID(temp->prev()->getID()+1);
    281     temp->setPeer(event->peer);
    282     COUT(3) << "Con.Man: added client id: " << temp->getID() << std::endl;
    283     return true;
    284   }
     296
    285297
    286298  int ConnectionManager::getClientID(ENetPeer peer) {
     
    316328      ++it;
    317329    }
    318     sendPackets();
     330    //sendPackets();
    319331    COUT(4) << "syncClassid:\tall synchClassID packets have been sent" << std::endl;
    320332  }
    321333
    322   bool ConnectionManager::createClient(int clientID){
    323     ClientInformation *temp = head_->findClient(clientID);
    324     if(!temp){
    325       COUT(2) << "Conn.Man. could not create client with id: " << clientID << std::endl;
    326       return false;
    327     }
    328     COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
    329     syncClassid(temp->getID());
    330     COUT(4) << "creating spaceship for clientid: " << temp->getID() << std::endl;
    331     // TODO: this is only a hack, untill we have a possibility to define default player-join actions
    332     if(!createShip(temp))
    333       COUT(2) << "Con.Man. could not create ship for clientid: " << clientID << std::endl;
    334     else
    335       COUT(3) << "created spaceship" << std::endl;
    336     temp->setSynched(true);
    337     COUT(3) << "sending welcome" << std::endl;
    338     sendWelcome(temp->getID(), temp->getShipID(), true);
    339     return true;
    340   }
    341  
    342   bool ConnectionManager::removeClient(int clientID){
    343     orxonox::Iterator<orxonox::SpaceShip> it = orxonox::ObjectList<orxonox::SpaceShip>::start();
    344     ClientInformation *client = head_->findClient(clientID);
    345     if(!client)
    346       return false;
    347     while(it){
    348       if(it->objectID!=client->getShipID()){
    349         ++it;
    350         continue;
    351       }
    352       orxonox::Iterator<orxonox::SpaceShip> temp=it;
    353       ++it;
    354       delete  *temp;
    355       return head_->removeClient(clientID);
    356     }
    357     return false;
    358   }
    359  
    360   bool ConnectionManager::createShip(ClientInformation *client){
    361     if(!client)
    362       return false;
    363     orxonox::Identifier* id = ID("SpaceShip");
    364     if(!id){
    365       COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;
    366       return false;
    367     }
    368     orxonox::SpaceShip *no = dynamic_cast<orxonox::SpaceShip *>(id->fabricate());
    369     no->setPosition(orxonox::Vector3(0,80,0));
    370     no->setScale(10);
    371     no->setYawPitchRoll(orxonox::Degree(-90),orxonox::Degree(-90),orxonox::Degree(0));
    372     no->setMesh("assff.mesh");
    373     no->setMaxSpeed(500);
    374     no->setMaxSideAndBackSpeed(50);
    375     no->setMaxRotation(1.0);
    376     no->setTransAcc(200);
    377     no->setRotAcc(3.0);
    378     no->setTransDamp(75);
    379     no->setRotDamp(1.0);
    380     no->setCamera("cam_"+client->getID());
    381     no->classID = id->getNetworkID();
    382     no->create();
    383    
    384     client->setShipID(no->objectID);
    385     return true;
    386   }
     334 
    387335 
    388336  bool ConnectionManager::removeShip(ClientInformation *client){
     
    399347  bool ConnectionManager::sendWelcome(int clientID, int shipID, bool allowed){
    400348    if(addPacket(packet_gen.generateWelcome(clientID, shipID, allowed),clientID)){
    401       sendPackets();
     349      //sendPackets();
    402350      return true;
    403351    }else
     
    406354 
    407355  void ConnectionManager::disconnectClient(ClientInformation *client){
    408     enet_peer_disconnect(client->getPeer(), 0);
     356    {
     357      boost::recursive_mutex::scoped_lock lock(enet_mutex_);
     358      enet_peer_disconnect(client->getPeer(), 0);
     359      lock.unlock();
     360    }
    409361    removeShip(client);
    410362  }
     
    418370 
    419371 
    420 //   int ConnectionManager::getNumberOfClients() {
    421 //     
    422 //     return clientsShip.size();
    423 //   }
    424  
    425   /*void ConnectionManager::addClientsObjectID( int clientID, int objectID ) {
    426   COUT(4) << "ship of client: " << clientID << ": " << objectID << " mapped" << std::endl;
    427   clientsShip.insert( std::make_pair( clientID, objectID ) );
     372
    428373}
    429 
    430   int ConnectionManager::getClientsShipID( int clientID ) {
    431   return clientsShip[clientID];
    432 }
    433 
    434   int ConnectionManager::getObjectsClientID( int objectID ) {
    435   std::map<int, int>::iterator iter;
    436   for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
    437   if( iter->second == objectID ) return iter->first;
    438 }
    439   return -99;
    440 }
    441 
    442   void ConnectionManager::deleteClientIDReg( int clientID ) {
    443   clientsShip.erase( clientID );
    444 }
    445 
    446   void ConnectionManager::deleteObjectIDReg( int objectID ) {
    447   std::map<int, int>::iterator iter = clientsShip.begin();
    448   for( iter = clientsShip.begin(); iter != clientsShip.end(); iter++ ) {
    449   if( iter->second == objectID ) break;
    450 }
    451   clientsShip.erase( iter->first );
    452 }*/
    453 }
Note: See TracChangeset for help on using the changeset viewer.