Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

the clients can now connect to the proxy server and get synchronized somehow there is still some synch that needs some more work: the messages are not sent to the server as they should (since there is only proxy) and the network game rules will have to be adjusted

File size: 10.5 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
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 ( SharedNetworkData::getInstance()->isMasterServer() ||  SharedNetworkData::getInstance()->isProxyServerActive())
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_BUT_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( SharedNetworkData::getInstance()->isMasterServer() ||  SharedNetworkData::getInstance()->isProxyServerActive());
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 ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
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)->getClassCName(), (*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 ( (SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/) && userId !=  SharedNetworkData::getInstance()->getHostID() )
308  {
309    MessageManager::getInstance()->sendMessage( messageId, data, dataLength, RT_ALL_BUT_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 ( SharedNetworkData::getInstance()->isMasterServer() /*|| SharedNetworkData::getInstance()->isProxyServerActive()*/)
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_BUT_ME, 0, MP_HIGHBANDWIDTH );
353
354
355  delete [] buf;
356}
357
358
359
Note: See TracBrowser for help on using the repository browser.