Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/proxy/src/lib/network/network_game_manager.cc @ 9522

Last change on this file since 9522 was 9522, checked in by patrick, 18 years ago

new the message handler is checking, if this message is also for the local host. if not the system tries to relay the message

File size: 10.9 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: Christoph Renner rennerc@ee.ethz.ch
13   co-programmer:   Patrick Boenzli  boenzlip@orxonox.ethz.ch
14
15     June 2006: finishing work on the network stream for pps presentation (rennerc@ee.ethz.ch)
16     July 2006: some code rearangement and integration of the proxy server mechanism (boenzlip@ee.ethz.ch)
17*/
18
19
20
21#define DEBUG_MODULE_NETWORK
22
23#include "util/loading/factory.h"
24#include "state.h"
25#include "class_list.h"
26#include "debug.h"
27
28#include "network_stream.h"
29#include "shared_network_data.h"
30#include "converter.h"
31#include "message_manager.h"
32
33#include "playable.h"
34#include "player.h"
35
36#include "game_world.h"
37
38#include "game_rules.h"
39#include "network_game_rules.h"
40
41#include "network_game_manager.h"
42
43#include "multiplayer_team_deathmatch.h"
44
45#include "preferences.h"
46
47
48
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()->isMasterServer() ||  SharedNetworkData::getInstance()->isProxyServerActive());
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  playable.setTeam(team);
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 messageType
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( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
169{
170
171  PRINTF(0)(" del synchronizeable\n");
172
173  if ( SharedNetworkData::getInstance()->isMasterServer() ||
174       SharedNetworkData::getInstance()->isProxyServerActive() && SharedNetworkData::getInstance()->isUserClient(senderId))
175  {
176    PRINTF(0)("Recieved DeleteSynchronizeable message from client %d!\n", senderId);
177    return true;
178  }
179
180  int uniqueId = 0;
181  int len = Converter::byteArrayToInt( data, &uniqueId );
182
183  if ( len != dataLength )
184  {
185    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
186    return true;
187  }
188
189  const std::list<BaseObject*> * list = ClassList::getList( CL_SYNCHRONIZEABLE );
190
191  for ( std::list<BaseObject*>::const_iterator it = list->begin(); it != list->end(); it++ )
192  {
193    if ( dynamic_cast<Synchronizeable*>(*it)->getUniqueID() == uniqueId )
194    {
195      if ( (*it)->isA(CL_PLAYABLE) )
196      {
197        getInstance()->playablesToDelete.push_back( dynamic_cast<Playable*>(*it) );
198        return true;
199      }
200
201      delete dynamic_cast<Synchronizeable*>(*it);
202      return true;
203    }
204  }
205
206  return true;
207}
208
209/**
210 * removes synchronizeable (also on clients)
211 * @param uniqueId uniqueid to delete
212 */
213void NetworkGameManager::removeSynchronizeable( int uniqueId )
214{
215  byte buf[INTSIZE];
216
217  assert( Converter::intToByteArray( uniqueId, buf, INTSIZE ) == INTSIZE );
218
219  MessageManager::getInstance()->sendMessage( MSGID_DELETESYNCHRONIZEABLE, buf, INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
220}
221
222
223
224/**
225 * handler for MSGID_PREFEREDTEAM message
226 * @param messageType
227 * @param data
228 * @param dataLength
229 * @param someData
230 * @param userId
231 * @return
232 */
233bool NetworkGameManager::preferedTeamHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
234{
235  assert( SharedNetworkData::getInstance()->isMasterServer() /*||  SharedNetworkData::getInstance()->isProxyServerActive()*/);
236
237  int teamId = 0;
238  int len = Converter::byteArrayToInt( data, &teamId );
239
240  if ( len != dataLength )
241  {
242    PRINTF(2)("Recieved DeleteSynchronizeable message with incorrect size (%d) from client %d!\n", dataLength, senderId);
243    return true;
244  }
245
246  NetworkGameManager::getInstance()->setPreferedTeam( senderId, teamId );
247
248  return true;
249}
250
251
252/**
253 * this actualy sets the new prefered team id
254 * @param userId: the user that changes team
255 * @param teamId: the new team id for the user
256 */
257void NetworkGameManager::setPreferedTeam( int userId, int teamId )
258{
259  if ( !PlayerStats::getStats( userId ) )
260    return;
261
262  PlayerStats & stats = *(PlayerStats::getStats( userId ));
263
264  stats.setPreferedTeamId( teamId );
265}
266
267
268/**
269 * set prefered team for this host
270 * @param teamId
271 */
272void NetworkGameManager::prefereTeam( int teamId )
273{
274  if ( SharedNetworkData::getInstance()->isMasterServer() )
275    this->setPreferedTeam( SharedNetworkData::getInstance()->getHostID(), teamId );
276  else
277  {
278    byte buf[INTSIZE];
279
280    assert( Converter::intToByteArray( teamId, buf, INTSIZE) == INTSIZE );
281
282    // send this message to the master server
283    MessageManager::getInstance()->sendMessage( MSGID_PREFEREDTEAM, buf, INTSIZE, RT_USER, NET_ID_MASTER_SERVER, MP_HIGHBANDWIDTH );
284  }
285}
286
287/**
288 * this function will be called periodically by networkManager
289 * @param ds time elapsed since last call of tick
290 */
291void NetworkGameManager::tick( float ds )
292{
293  //delete playables if they are not assigned to local player anymore
294  for ( std::list<Playable*>::iterator it = playablesToDelete.begin(); it != playablesToDelete.end();  )
295  {
296    if ( State::getPlayer()->getPlayable() != *it )
297    {
298      const std::list<BaseObject*> * list = ClassList::getList( CL_PLAYABLE );
299
300      if ( list && std::find( list->begin(), list->end(), *it ) != list->end() )
301      {
302        PRINTF(0)("Delete unused playable: %s owner: %d\n", (*it)->getClassCName(), (*it)->getOwner() );
303        std::list<Playable*>::iterator delit = it;
304        it++;
305        delete *delit;
306        playablesToDelete.erase( delit );
307        continue;
308      }
309    }
310    it++;
311  }
312}
313
314
315
316bool NetworkGameManager::chatMessageHandler( MessageType messageType, byte * data, int dataLength, void * someData, int senderId, int destinationId  )
317{
318  PRINTF(0)("NetworkGameManager::chatMessageHandler %d %d\n", senderId, SharedNetworkData::getInstance()->getHostID() );
319  if ( (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/) && senderId !=  SharedNetworkData::getInstance()->getHostID() )
320  {
321    MessageManager::getInstance()->sendMessage( messageType, data, dataLength, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
322  }
323
324  assert( State::getGameRules() );
325  assert( State::getGameRules()->isA( CL_NETWORK_GAME_RULES ) );
326
327  NetworkGameRules & rules = *(dynamic_cast<NetworkGameRules*>(State::getGameRules()));
328
329  if ( dataLength < 3*INTSIZE )
330  {
331    PRINTF(2)("got too small chatmessage from client %d\n", senderId);
332
333    return true;
334  }
335
336  int chatType = 0;
337  Converter::byteArrayToInt( data, &chatType);
338  int senderUserId = 0;
339  Converter::byteArrayToInt( data+INTSIZE, &senderUserId );
340  std::string message;
341  Converter::byteArrayToString( data+2*INTSIZE, message, dataLength-2*INTSIZE );
342
343  rules.handleChatMessage( senderUserId, message, chatType);
344
345  return true;
346}
347
348/**
349 * send chat message
350 * @param message message text
351 * @param messageType some int
352 */
353void NetworkGameManager::sendChatMessage( const std::string & message, int messageType )
354{
355  byte * buf = new byte[message.length()+3*INTSIZE];
356
357  assert( Converter::intToByteArray( messageType, buf, INTSIZE ) == INTSIZE );
358  assert( Converter::intToByteArray( SharedNetworkData::getInstance()->getHostID(), buf+INTSIZE, INTSIZE ) == INTSIZE );
359  assert( Converter::stringToByteArray(message, buf+2*INTSIZE, message.length()+INTSIZE) == message.length()+INTSIZE );
360
361  if ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
362    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
363  else
364    MessageManager::getInstance()->sendMessage( MSGID_CHATMESSAGE, buf, message.length()+3*INTSIZE, RT_ALL_BUT_ME, NET_UNASSIGNED, MP_HIGHBANDWIDTH );
365
366
367  delete [] buf;
368}
369
370
371
Note: See TracBrowser for help on using the repository browser.