/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli (patrick@orxonox.ethz.ch) */ #include "proxy_control.h" #include "class_list.h" #include "state.h" #include "shared_network_data.h" #include "network_game_manager.h" #include "ip.h" #include "peer_info.h" #include "converter.h" #include "preferences.h" #include "debug.h" #include "monitor/network_monitor.h" ProxyControl* ProxyControl::singletonRef = NULL; /** * constructor */ ProxyControl::ProxyControl() { this->setClassID( CL_PROXY_CONTROL, "ProxyControl" ); MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_NEWCLIENT, messageHandlerNewClient, NULL ); MessageManager::getInstance()->registerMessageHandler( MSGID_PROXY_LEAVECLIENT, messageHandlerLeaveClient, NULL ); PRINTF(0)("ProxyControl created\n"); } /** * standard deconstructor */ ProxyControl::~ProxyControl() { ProxyControl::singletonRef = NULL; } /** * override this function to be notified on change * of your registred variables. * @param id id's which have changed */ void ProxyControl::varChangeHandler( std::list< int > & id ) { // if ( std::find( id.begin(), id.end(), playableUniqueId_handle ) != id.end() ) // { // this->setPlayableUniqueId( this->playableUniqueId ); // // PRINTF(0)("uniqueID changed %d %d %d\n", userId, SharedNetworkData::getInstance()->getHostID(), getUniqueID()); // } } /** * signals new client connected to this local proxy * * byte 0 - 3 : userId * byte 4 - 7 : ip address (IPaddress.host) * * @param userId userId of the new client */ void ProxyControl::signalNewClient(int userId) { PRINTF(0)("Signaling new Client: %i\n", userId); // make sure we are a proxy server assert(SharedNetworkData::getInstance()->isProxyServerActive()); byte data[2 * INTSIZE]; // write the userId in the message assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE ); // and the ip as an int PeerInfo* pInfo = SharedNetworkData::getInstance()->getNetworkMonitor()->getPeerByUserId(userId); assert(pInfo != NULL); assert( Converter::intToByteArray( pInfo->ip.host(), data + INTSIZE, INTSIZE ) == INTSIZE ); MessageManager::getInstance()->sendMessage( MSGID_PROXY_NEWCLIENT, data, 2*INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH ); } /** * this is the handler for proxy signals: new clients * * @param messageType the type of the message * @param data message data * @param dataLength length of the message data * @param someData some other atteched data * @param senderId id of the sender client * @param destinationId id of the destination client * @return true if succeeded */ bool ProxyControl::messageHandlerNewClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId ) { // body data length correct? if ( dataLength != 2 * INTSIZE ) { PRINTF(2)("new client message has wrong size: %d\n", dataLength ); return true; } // read the userId fromt he message body int newClientId = 0; assert( Converter::byteArrayToInt( data, &newClientId) == INTSIZE ); // now read the ip address int ipHost = 0; assert( Converter::byteArrayToInt( data + INTSIZE, &ipHost) == INTSIZE ); // register the new node at the network monitor NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor(); PeerInfo* pInfo = new PeerInfo(); pInfo->bLocal = false; pInfo->ip = IP(ipHost, 9999); pInfo->nodeType = NET_CLIENT; pInfo->userId = newClientId; netMon->addNode(pInfo); PRINTF(0)("Got Signal: from %i new player arrived with userId: %i and ip: %i\n", senderId, newClientId, pInfo->ip.ipString().c_str()); // part for the master server if( SharedNetworkData::getInstance()->isMasterServer()) { // we now create the new player ship and stuff... NetworkGameManager::getInstance()->signalNewPlayer(newClientId); } return true; } /** * signals client disconnect * @param userId userId of the old client */ void ProxyControl::signalLeaveClient(int userId) { PRINTF(0)("Signaling new Client: %i\n", userId); // make sure we are a proxy server assert(SharedNetworkData::getInstance()->isProxyServerActive()); byte data[INTSIZE]; assert( Converter::intToByteArray( userId, data, INTSIZE ) == INTSIZE ); MessageManager::getInstance()->sendMessage( MSGID_PROXY_LEAVECLIENT, data, INTSIZE, RT_SERVER, NET_UNASSIGNED, MP_HIGHBANDWIDTH ); } /** * this is the handler for proxy signals: removing clients * * @param messageType the type of the message * @param data message data * @param dataLength length of the message data * @param someData some other atteched data * @param senderId id of the sender client * @param destinationId id of the destination client * @return true if succeeded */ bool ProxyControl::messageHandlerLeaveClient( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId ) { // body data length correct? if ( dataLength != INTSIZE ) { PRINTF(2)("leave client message has wrong size: %d\n", dataLength ); return true; } // read the userId fromt he message body int leaveClientId = 0; assert( Converter::byteArrayToInt( data, &leaveClientId) == INTSIZE ); // remove the node from the network monitor NetworkMonitor* netMon = SharedNetworkData::getInstance()->getNetworkMonitor(); netMon->removeNode( netMon->getPeerByUserId(leaveClientId)); PRINTF(0)("Got Signal: from %i new player left with userId: %i\n", senderId, leaveClientId); // part for the master server if( SharedNetworkData::getInstance()->isMasterServer()) { // we now create the new player ship and stuff... NetworkGameManager::getInstance()->signalLeftPlayer(leaveClientId); } else if(SharedNetworkData::getInstance()->isProxyServerActive()) { } return true; }