Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/network_game_manager.cc @ 9008

Last change on this file since 9008 was 9008, checked in by bensch, 18 years ago

orxonox/trunk: merged the network bak to the trunk
merged with command:
svn merge -r8804:HEAD https://svn.orxonox.net/orxonox/branches/multi_player_map .

conflicts all resolved in favour of the branche

File size: 9.5 KB
RevLine 
[6067]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Benjamin Wuest
13   co-programmer: ...
14*/
15
16
17/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
18   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
19*/
20#define DEBUG_MODULE_NETWORK
21
[7193]22#include "util/loading/factory.h"
[7349]23#include "state.h"
24#include "class_list.h"
[8623]25#include "debug.h"
[7349]26
[6341]27#include "network_stream.h"
[7349]28#include "shared_network_data.h"
[6341]29#include "converter.h"
[7954]30#include "message_manager.h"
[6341]31
[6498]32#include "playable.h"
33#include "player.h"
[6424]34
[7349]35#include "game_world.h"
[6424]36
[8068]37#include "game_rules.h"
38#include "network_game_rules.h"
39
[6116]40#include "network_game_manager.h"
[6067]41
[9008]42#include "multiplayer_team_deathmatch.h"
[6067]43
[9008]44
[6067]45/* using namespace std is default, this needs to be here */
46using namespace std;
47
[6341]48NetworkGameManager* NetworkGameManager::singletonRef = NULL;
49
[6067]50/*!
51 * Standard constructor
52 */
[6116]53NetworkGameManager::NetworkGameManager()
[6695]54  : Synchronizeable()
[6067]55{
[6341]56  PRINTF(0)("START\n");
57
[6067]58  /* set the class id for the base object */
[6341]59  this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
60
[6695]61  this->setSynchronized(true);
[8623]62 
[8068]63  MessageManager::getInstance()->registerMessageHandler( MSGID_DELETESYNCHRONIZEABLE, delSynchronizeableHandler, NULL );
[8147]64  MessageManager::getInstance()->registerMessageHandler( MSGID_PREFEREDTEAM, preferedTeamHandler, NULL );
[8623]65  MessageManager::getInstance()->registerMessageHandler( MSGID_CHATMESSAGE, chatMessageHandler, NULL );
66 
[8068]67  this->gameState = 0;
68  registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState" ) );
[6067]69}
70
71/*!
72 * Standard destructor
73 */
[6116]74NetworkGameManager::~NetworkGameManager()
[6067]75{
[8623]76  delete MessageManager::getInstance();
77 
78  PlayerStats::deleteAllPlayerStats();
[6067]79}
80
[6341]81
[8068]82/**
83 * insert new player into game
[8623]84 * @param userId
85 * @return
[6067]86 */
[8068]87bool NetworkGameManager::signalNewPlayer( int userId )
[6067]88{
[8068]89  assert( SharedNetworkData::getInstance()->isGameServer() );
90  assert( State::getGameRules() );
91  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
[8623]92 
[8068]93  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
[8623]94 
[8068]95  int team = rules.getTeamForNewUser();
[8147]96  ClassID playableClassId = rules.getPlayableClassId( userId, team );
97  std::string playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
[8623]98 
[8068]99  BaseObject * bo = Factory::fabricate( playableClassId );
[8623]100 
[8068]101  assert( bo != NULL );
102  assert( bo->isA( CL_PLAYABLE ) );
[8623]103 
[8068]104  Playable & playable = *(dynamic_cast<Playable*>(bo));
[8623]105 
106  if (  playableModel != "" )
107    playable.loadModel( playableModel );
[8068]108  playable.setOwner( userId );
109  playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
110  playable.setSynchronized( true );
[8623]111 
[8068]112  PlayerStats * stats = rules.getNewPlayerStats( userId );
[8623]113 
[8068]114  stats->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
115  stats->setSynchronized( true );
[8708]116  stats->setOwner( SharedNetworkData::getInstance()->getHostID() );
[8623]117 
[8068]118  stats->setTeamId( team );
119  stats->setPlayableClassId( playableClassId );
120  stats->setPlayableUniqueId( playable.getUniqueID() );
121  stats->setModelFileName( playableModel );
[8623]122 
[9008]123  if ( rules.isA( CL_MULTIPLAYER_TEAM_DEATHMATCH ) )
124    dynamic_cast<MultiplayerTeamDeathmatch*>(&rules)->respawnPlayable( &playable, team, 0.0f );
125 
[8228]126  return true;
[6737]127}
128
[6341]129
130/**
[8068]131 * remove player from game
[8623]132 * @param userID
133 * @return
[6341]134 */
[8068]135bool NetworkGameManager::signalLeftPlayer(int userID)
[6341]136{
[8228]137  if ( PlayerStats::getStats( userID ) )
138  {
139    if ( PlayerStats::getStats( userID )->getPlayable() )
140      delete PlayerStats::getStats( userID )->getPlayable();
141    delete PlayerStats::getStats( userID );
142  }
[8623]143 
[8228]144  return true;
[6341]145}
146
147
148
149/**
[8068]150 * handler for remove synchronizeable messages
[8623]151 * @param messageId
152 * @param data
153 * @param dataLength
154 * @param someData
155 * @param userId
[8068]156 * @return true on successfull handling else handler will be called again
[6341]157 */
[8068]158bool NetworkGameManager::delSynchronizeableHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
[6341]159{
[8068]160  if ( getInstance()->isServer() )
[6341]161  {
[8068]162    PRINTF(2)("Recieved DeleteSynchronizeable message from client %d!\n", userId);
163    return true;
[6341]164  }
[8623]165 
[8068]166  int uniqueId = 0;
167  int len = Converter::byteArrayToInt( data, &uniqueId );
[8623]168 
[8068]169  if ( len != dataLength )
[6341]170  {
[8068]171    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
172    return true;
[6341]173  }
[8623]174 
[8068]175  const std::list<BaseObject*> * list = ClassList::getList( CL_SYNCHRONIZEABLE );
[8623]176 
[8068]177  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
[6341]178  {
[8068]179    if ( dynamic_cast<Synchronizeable*>(*it)->getUniqueID() == uniqueId )
[6341]180    {
[8147]181      if ( (*it)->isA(CL_PLAYABLE) )
182      {
183        getInstance()->playablesToDelete.push_back( dynamic_cast<Playable*>(*it) );
184        return true;
185      }
[8623]186     
[8068]187      delete dynamic_cast<Synchronizeable*>(*it);
188      return true;
[6341]189    }
190  }
[8623]191 
[8228]192  return true;
[6341]193}
194
[6695]195/**
[8068]196 * removes synchronizeable (also on clients)
197 * @param uniqueId uniqueid to delete
[6695]198 */
[8068]199void NetworkGameManager::removeSynchronizeable( int uniqueId )
[6695]200{
[8068]201  byte buf[INTSIZE];
[8623]202 
[8068]203  assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
[8362]204
[8068]205  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
[7954]206}
207
[6341]208
209
[8147]210/**
211 * handler for MSGID_PREFEREDTEAM message
[8623]212 * @param messageId
213 * @param data
214 * @param dataLength
215 * @param someData
216 * @param userId
217 * @return
[8147]218 */
219bool NetworkGameManager::preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
220{
221  assert( NetworkGameManager::getInstance()->isServer() );
[8623]222 
[8147]223  int teamId = 0;
224  int len = Converter::byteArrayToInt( data, &teamId );
[8623]225 
[8147]226  if ( len != dataLength )
227  {
228    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
229    return true;
230  }
[8623]231 
[8147]232  NetworkGameManager::getInstance()->setPreferedTeam( userId, teamId );
[8623]233 
[8228]234  return true;
[8147]235}
[6341]236
[8147]237void NetworkGameManager::setPreferedTeam( int userId, int teamId )
238{
239  if ( !PlayerStats::getStats( userId ) )
240    return;
[8623]241 
[8147]242  PlayerStats & stats = *(PlayerStats::getStats( userId ));
[8623]243 
[8147]244  stats.setPreferedTeamId( teamId );
245}
[7954]246
[8147]247/**
248 * set prefered team for this host
[8623]249 * @param teamId
[8147]250 */
251void NetworkGameManager::prefereTeam( int teamId )
252{
253  if ( isServer() )
[8708]254    setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
[8147]255  else
256  {
257    byte buf[INTSIZE];
[8623]258   
[8147]259    assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
[8623]260   
[8147]261    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, 0, MP_HIGHBANDWIDTH );
262  }
263}
[6341]264
[8147]265/**
266 * this function will be called periodically by networkManager
267 * @param ds time elapsed since last call of tick
268 */
269void NetworkGameManager::tick( float ds )
270{
271  //delete playables if they are not assigned to local player anymore
272  for ( std::list<Playable*>::iterator it = playablesToDelete.begin(); it != playablesToDelete.end();  )
273  {
274    if ( State::getPlayer()->getPlayable() != *it )
275    {
276      PRINTF(0)("Delete unused playable: %s owner: %d\n", (*it)->getClassName(), (*it)->getOwner() );
277      std::list<Playable*>::iterator delit = it;
278      it++;
279      delete *delit;
280      playablesToDelete.erase( delit );
281      continue;
282    }
283    it++;
284  }
285}
286
287
288
[8623]289bool NetworkGameManager::chatMessageHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
290{
[8708]291  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", userId, SharedNetworkData::getInstance()->getHostID() );
292  if ( NetworkGameManager::getInstance()->isServer() && userId !=  SharedNetworkData::getInstance()->getHostID() )
293  {
294    MessageManager::getInstance()->sendMessage( messageId, data, dataLength, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
295  }
296 
[8623]297  assert( State::getGameRules() );
298  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
299 
300  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
301 
[8708]302  if ( dataLength < 3*INTSIZE )
[8623]303  {
304    PRINTF(2)("got too small chatmessage from client %d\n", userId);
305   
306    return true;
307  }
308 
309  int messageType = 0;
310  Converter::byteArrayToInt( data, &messageType );
[8708]311  int senderUserId = 0;
312  Converter::byteArrayToInt( data+INTSIZE, &senderUserId );
[8623]313  std::string message;
[8708]314  Converter::byteArrayToString( data+2*INTSIZE, message, dataLength-2*INTSIZE );
[8623]315 
[8708]316  rules.handleChatMessage( senderUserId, message, messageType );
[8147]317
[8623]318  return true;
319}
320
321/**
322 * send chat message
323 * @param message message text
324 * @param messageType some int
325 */
[8708]326void NetworkGameManager::sendChatMessage( const std::string & message, int messageType )
[8623]327{
[8708]328  byte * buf = new byte[message.length()+3*INTSIZE];
[8623]329
330  assert( Converter::intToByteArray( messageType, buf, INTSIZE ) == INTSIZE );
[8708]331  assert( Converter::intToByteArray( SharedNetworkData::getInstance()->getHostID(), buf+INTSIZE, INTSIZE ) == INTSIZE );
332  assert( Converter::stringToByteArray(message, buf+2*INTSIZE, message.length()+INTSIZE) == message.length()+INTSIZE );
[8623]333 
[8708]334  if ( this->isServer() )
335    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, 0, MP_HIGHBANDWIDTH );
[8623]336  else
[8708]337    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
338
[8623]339 
340  delete [] buf;
341}
342
343
344
Note: See TracBrowser for help on using the repository browser.