Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: merged the Presentation back

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