Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged the presentation back

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