Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged network back
merged with command:
svn merge -r8625:HEAD https://svn.orxonox.net/orxonox/branches/network .
no conflicts

File size: 9.4 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
42
43/* using namespace std is default, this needs to be here */
44using namespace std;
45
[6341]46NetworkGameManager* NetworkGameManager::singletonRef = NULL;
47
[6067]48/*!
49 * Standard constructor
50 */
[6116]51NetworkGameManager::NetworkGameManager()
[6695]52  : Synchronizeable()
[6067]53{
[6341]54  PRINTF(0)("START\n");
55
[6067]56  /* set the class id for the base object */
[6341]57  this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
58
[6695]59  this->setSynchronized(true);
[8623]60 
[8068]61  MessageManager::getInstance()->registerMessageHandler( MSGID_DELETESYNCHRONIZEABLE, delSynchronizeableHandler, NULL );
[8147]62  MessageManager::getInstance()->registerMessageHandler( MSGID_PREFEREDTEAM, preferedTeamHandler, NULL );
[8623]63  MessageManager::getInstance()->registerMessageHandler( MSGID_CHATMESSAGE, chatMessageHandler, NULL );
64 
[8068]65  this->gameState = 0;
66  registerVar( new SynchronizeableInt( &gameState, &gameState, "gameState" ) );
[6067]67}
68
69/*!
70 * Standard destructor
71 */
[6116]72NetworkGameManager::~NetworkGameManager()
[6067]73{
[8623]74  delete MessageManager::getInstance();
75 
76  PlayerStats::deleteAllPlayerStats();
[6067]77}
78
[6341]79
[8068]80/**
81 * insert new player into game
[8623]82 * @param userId
83 * @return
[6067]84 */
[8068]85bool NetworkGameManager::signalNewPlayer( int userId )
[6067]86{
[8068]87  assert( SharedNetworkData::getInstance()->isGameServer() );
88  assert( State::getGameRules() );
89  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
[8623]90 
[8068]91  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
[8623]92 
[8068]93  int team = rules.getTeamForNewUser();
[8147]94  ClassID playableClassId = rules.getPlayableClassId( userId, team );
95  std::string playableModel = rules.getPlayableModelFileName( userId, team, playableClassId );
[8623]96 
[8068]97  BaseObject * bo = Factory::fabricate( playableClassId );
[8623]98 
[8068]99  assert( bo != NULL );
100  assert( bo->isA( CL_PLAYABLE ) );
[8623]101 
[8068]102  Playable & playable = *(dynamic_cast<Playable*>(bo));
[8623]103 
104  if (  playableModel != "" )
105    playable.loadModel( playableModel );
[8068]106  playable.setOwner( userId );
107  playable.setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
108  playable.setSynchronized( true );
[8623]109 
[8068]110  PlayerStats * stats = rules.getNewPlayerStats( userId );
[8623]111 
[8068]112  stats->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
113  stats->setSynchronized( true );
[8708]114  stats->setOwner( SharedNetworkData::getInstance()->getHostID() );
[8623]115 
[8068]116  stats->setTeamId( team );
117  stats->setPlayableClassId( playableClassId );
118  stats->setPlayableUniqueId( playable.getUniqueID() );
119  stats->setModelFileName( playableModel );
[8623]120 
[8228]121  return true;
[6737]122}
123
[6341]124
125/**
[8068]126 * remove player from game
[8623]127 * @param userID
128 * @return
[6341]129 */
[8068]130bool NetworkGameManager::signalLeftPlayer(int userID)
[6341]131{
[8228]132  if ( PlayerStats::getStats( userID ) )
133  {
134    if ( PlayerStats::getStats( userID )->getPlayable() )
135      delete PlayerStats::getStats( userID )->getPlayable();
136    delete PlayerStats::getStats( userID );
137  }
[8623]138 
[8228]139  return true;
[6341]140}
141
142
143
144/**
[8068]145 * handler for remove synchronizeable messages
[8623]146 * @param messageId
147 * @param data
148 * @param dataLength
149 * @param someData
150 * @param userId
[8068]151 * @return true on successfull handling else handler will be called again
[6341]152 */
[8068]153bool NetworkGameManager::delSynchronizeableHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
[6341]154{
[8068]155  if ( getInstance()->isServer() )
[6341]156  {
[8068]157    PRINTF(2)("Recieved DeleteSynchronizeable message from client %d!\n", userId);
158    return true;
[6341]159  }
[8623]160 
[8068]161  int uniqueId = 0;
162  int len = Converter::byteArrayToInt( data, &uniqueId );
[8623]163 
[8068]164  if ( len != dataLength )
[6341]165  {
[8068]166    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
167    return true;
[6341]168  }
[8623]169 
[8068]170  const std::list<BaseObject*> * list = ClassList::getList( CL_SYNCHRONIZEABLE );
[8623]171 
[8068]172  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
[6341]173  {
[8068]174    if ( dynamic_cast<Synchronizeable*>(*it)->getUniqueID() == uniqueId )
[6341]175    {
[8147]176      if ( (*it)->isA(CL_PLAYABLE) )
177      {
178        getInstance()->playablesToDelete.push_back( dynamic_cast<Playable*>(*it) );
179        return true;
180      }
[8623]181     
[8068]182      delete dynamic_cast<Synchronizeable*>(*it);
183      return true;
[6341]184    }
185  }
[8623]186 
[8228]187  return true;
[6341]188}
189
[6695]190/**
[8068]191 * removes synchronizeable (also on clients)
192 * @param uniqueId uniqueid to delete
[6695]193 */
[8068]194void NetworkGameManager::removeSynchronizeable( int uniqueId )
[6695]195{
[8068]196  byte buf[INTSIZE];
[8623]197 
[8068]198  assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
[8362]199
[8068]200  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
[7954]201}
202
[6341]203
204
[8147]205/**
206 * handler for MSGID_PREFEREDTEAM message
[8623]207 * @param messageId
208 * @param data
209 * @param dataLength
210 * @param someData
211 * @param userId
212 * @return
[8147]213 */
214bool NetworkGameManager::preferedTeamHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
215{
216  assert( NetworkGameManager::getInstance()->isServer() );
[8623]217 
[8147]218  int teamId = 0;
219  int len = Converter::byteArrayToInt( data, &teamId );
[8623]220 
[8147]221  if ( len != dataLength )
222  {
223    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, userId);
224    return true;
225  }
[8623]226 
[8147]227  NetworkGameManager::getInstance()->setPreferedTeam( userId, teamId );
[8623]228 
[8228]229  return true;
[8147]230}
[6341]231
[8147]232void NetworkGameManager::setPreferedTeam( int userId, int teamId )
233{
234  if ( !PlayerStats::getStats( userId ) )
235    return;
[8623]236 
[8147]237  PlayerStats & stats = *(PlayerStats::getStats( userId ));
[8623]238 
[8147]239  stats.setPreferedTeamId( teamId );
240}
[7954]241
[8147]242/**
243 * set prefered team for this host
[8623]244 * @param teamId
[8147]245 */
246void NetworkGameManager::prefereTeam( int teamId )
247{
248  if ( isServer() )
[8708]249    setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
[8147]250  else
251  {
252    byte buf[INTSIZE];
[8623]253   
[8147]254    assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
[8623]255   
[8147]256    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, 0, MP_HIGHBANDWIDTH );
257  }
258}
[6341]259
[8147]260/**
261 * this function will be called periodically by networkManager
262 * @param ds time elapsed since last call of tick
263 */
264void NetworkGameManager::tick( float ds )
265{
266  //delete playables if they are not assigned to local player anymore
267  for ( std::list<Playable*>::iterator it = playablesToDelete.begin(); it != playablesToDelete.end();  )
268  {
269    if ( State::getPlayer()->getPlayable() != *it )
270    {
271      PRINTF(0)("Delete unused playable: %s owner: %d\n", (*it)->getClassName(), (*it)->getOwner() );
272      std::list<Playable*>::iterator delit = it;
273      it++;
274      delete *delit;
275      playablesToDelete.erase( delit );
276      continue;
277    }
278    it++;
279  }
280}
281
282
283
[8623]284bool NetworkGameManager::chatMessageHandler( MessageId messageId, byte * data, int dataLength, void * someData, int userId )
285{
[8708]286  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", userId, SharedNetworkData::getInstance()->getHostID() );
287  if ( NetworkGameManager::getInstance()->isServer() && userId !=  SharedNetworkData::getInstance()->getHostID() )
288  {
289    MessageManager::getInstance()->sendMessage( messageId, data, dataLength, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
290  }
291 
[8623]292  assert( State::getGameRules() );
293  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
294 
295  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
296 
[8708]297  if ( dataLength < 3*INTSIZE )
[8623]298  {
299    PRINTF(2)("got too small chatmessage from client %d\n", userId);
300   
301    return true;
302  }
303 
304  int messageType = 0;
305  Converter::byteArrayToInt( data, &messageType );
[8708]306  int senderUserId = 0;
307  Converter::byteArrayToInt( data+INTSIZE, &senderUserId );
[8623]308  std::string message;
[8708]309  Converter::byteArrayToString( data+2*INTSIZE, message, dataLength-2*INTSIZE );
[8623]310 
[8708]311  rules.handleChatMessage( senderUserId, message, messageType );
[8147]312
[8623]313  return true;
314}
315
316/**
317 * send chat message
318 * @param message message text
319 * @param messageType some int
320 */
[8708]321void NetworkGameManager::sendChatMessage( const std::string & message, int messageType )
[8623]322{
[8708]323  byte * buf = new byte[message.length()+3*INTSIZE];
[8623]324
325  assert( Converter::intToByteArray( messageType, buf, INTSIZE ) == INTSIZE );
[8708]326  assert( Converter::intToByteArray( SharedNetworkData::getInstance()->getHostID(), buf+INTSIZE, INTSIZE ) == INTSIZE );
327  assert( Converter::stringToByteArray(message, buf+2*INTSIZE, message.length()+INTSIZE) == message.length()+INTSIZE );
[8623]328 
[8708]329  if ( this->isServer() )
330    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, 0, MP_HIGHBANDWIDTH );
[8623]331  else
[8708]332    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_NOT_ME, 0, MP_HIGHBANDWIDTH );
333
[8623]334 
335  delete [] buf;
336}
337
338
339
Note: See TracBrowser for help on using the repository browser.