Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/network/Client.cc @ 10480

Last change on this file since 10480 was 10464, checked in by landauf, 10 years ago

define ScopeID as integer constants instead of an enum. this allows to extend it and add new scopes outside of core.

  • Property svn:eol-style set to native
File size: 6.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Oliver Scheuss
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29//
30// C++ Implementation: Client
31//
32// Description:
33//
34//
35// Author:  Oliver Scheuss, (C) 2007
36//
37// Copyright: See COPYING file that comes with this distribution
38//
39//
40
41#include "Client.h"
42
43#include <cassert>
44
45#include "util/Clock.h"
46#include "util/Output.h"
47#include "synchronisable/Synchronisable.h"
48#include "packet/Chat.h"
49#include "packet/Gamestate.h"
50#include "FunctionCallManager.h"
51#include "core/CoreIncludes.h"
52#include "core/Game.h"
53#include "core/commandline/CommandLineParser.h"
54#include "core/singleton/ScopedSingletonIncludes.h"
55
56namespace orxonox
57{
58
59  ManageScopedSingleton( Client, ScopeID::ROOT, false );
60
61  /**
62  * Constructor for the Client class
63  * initializes the address and the port to default localhost:NETWORK_PORT
64  */
65  Client::Client():
66      isSynched_(false),
67      gameStateFailure_(false),
68      timeSinceLastUpdate_(0)
69  {
70    this->setDestination( CommandLineParser::getValue("dest").get<std::string>(), CommandLineParser::getValue("port") );
71  }
72
73  Client::~Client()
74  {
75    if ( ClientConnection::isConnected() )
76      closeConnection();
77  }
78
79  /**
80  * Establish the Connection to the Server
81  * @return true/false
82  */
83  bool Client::establishConnection()
84  {
85    Synchronisable::setClient(true);
86    if( ClientConnection::establishConnection() )
87    {
88      Host::setActive(true);
89      GamestateManager::addPeer(NETWORK_PEER_ID_SERVER);
90      return true;
91    }
92    else
93      return false;
94  }
95
96  /**
97  * closes the Connection to the Server
98  * @return true/false
99  */
100  bool Client::closeConnection()
101  {
102    Host::setActive(false);
103    GamestateManager::removePeer(NETWORK_PEER_ID_SERVER);
104    return ClientConnection::closeConnection();
105  }
106
107  void Client::setDestination(const std::string& serverAddress, unsigned int port)
108  {
109    ClientConnection::setServerAddress(serverAddress);
110    ClientConnection::setPort(port);
111  }
112
113  void Client::queuePacket(ENetPacket *packet, int clientID, uint8_t channelID)
114  {
115    ClientConnection::addPacket(packet, channelID);
116  }
117
118  void Client::printRTT()
119  {
120    orxout(message) << "Round trip time to server is " << ClientConnection::getRTT() << " ms" << endl;
121  }
122
123  /**
124   * @brief Sends a chat message to the server.
125   * @param message message to be sent
126   * @param sourceID the ID of the sender
127   * @param targetID the ID of the receiver
128   */
129  void Client::doSendChat(const std::string& message, unsigned int sourceID, unsigned int targetID)
130  {
131    // send the message to the server
132    packet::Chat* packet = new packet::Chat(message, sourceID, targetID);
133    packet->send(static_cast<Host*>(this));
134  }
135
136  /**
137   * @brief Gets called if a packet::Chat packet is received. Calls the parent function which passes the message to the listeners.
138   */
139  void Client::doReceiveChat(const std::string& message, unsigned int sourceID, unsigned int targetID)
140  {
141    // call the parent function which passes the message to the listeners
142    Host::doReceiveChat(message, sourceID, targetID);
143  }
144
145  /**
146   * Processes incoming packets, sends a gamestate to the server and does the cleanup
147   * @param time
148   */
149  void Client::update(const Clock& time)
150  {
151    //this steers our network frequency
152    timeSinceLastUpdate_+=time.getDeltaTime();
153    if(timeSinceLastUpdate_>=NETWORK_PERIOD)
154    {
155      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
156      if ( isConnected() && isSynched_ )
157      {
158        orxout(verbose, context::network) << "popping partial gamestate: " << endl;
159//         packet::Gamestate *gs = GamestateClient::getGamestate();
160        if( GamestateManager::update() )
161        {
162          std::vector<packet::Gamestate*> gamestates = GamestateManager::getGamestates();
163          std::vector<packet::Gamestate*>::iterator it;
164          for( it = gamestates.begin(); it != gamestates.end(); ++it )
165          {
166            (*it)->send( static_cast<Host*>(this) );
167          }
168        }
169        //assert(gs); <--- there might be the case that no data has to be sent, so its commented out now
170//         if(gs){
171//           orxout(verbose, context::network) << "client tick: sending gs " << gs << endl;
172//           if( !gs->send() )
173//             orxout(internal_warning, context::network) << "Problem adding partial gamestate to queue" << endl;
174//         // gs gets automatically deleted by enet callback
175//         }
176        FunctionCallManager::sendCalls(static_cast<Host*>(this));
177      }
178    }
179//     sendPackets(); // flush the enet queue
180
181    Connection::processQueue();
182    if(GamestateManager::processGamestates())
183    {
184      FunctionCallManager::processBufferedFunctionCalls();
185      if(!isSynched_)
186        isSynched_=true;
187    }
188//     GamestateManager::cleanup();;
189//     Connection::sendPackets();
190
191    return;
192  }
193
194  void Client::connectionClosed()
195  {
196    ObjectList<Synchronisable>::iterator it;
197    for(it = ObjectList<Synchronisable>::begin(); it; )
198    {
199      if( it->getSyncMode() != 0x0 )
200        (it++)->destroy();
201      else
202      {
203        ++it;
204      }
205    }
206    Game::getInstance().popState();
207    Game::getInstance().popState();
208  }
209
210  void Client::processPacket(packet::Packet* packet)
211  {
212    if( packet->isReliable() )
213    {
214      if( this->getLastReceivedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
215        packet->process(static_cast<Host*>(this));
216      else
217        this->packetQueue_.push_back(packet);
218    }
219    else
220      packet->process(static_cast<Host*>(this));
221  }
222}
Note: See TracBrowser for help on using the repository browser.