Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

network: implemented network cd system

File size: 24.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 "factory.h"
23#include "network_stream.h"
24#include "converter.h"
25
26#include "p_node.h"
27#include "state.h"
28#include "game_world.h"
29#include "world_entity.h"
30#include "playable.h"
31#include "player.h"
32#include "shared_network_data.h"
33
34#include "class_list.h"
35
36/* include your own header */
37#include "network_game_manager.h"
38
39
40/* using namespace std is default, this needs to be here */
41using namespace std;
42
43NetworkGameManager* NetworkGameManager::singletonRef = NULL;
44
45/*!
46 * Standard constructor
47 */
48NetworkGameManager::NetworkGameManager()
49  : Synchronizeable()
50{
51  PRINTF(0)("START\n");
52
53  /* set the class id for the base object */
54  this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
55
56  hasRequestedWorld = false;
57  this->setSynchronized(true);
58}
59
60/*!
61 * Standard destructor
62 */
63NetworkGameManager::~NetworkGameManager()
64{
65  for ( int i = 0; i<outBuffer.size(); i++)
66  {
67    if ( outBuffer[i].buffer )
68      delete outBuffer[i].buffer;
69  }
70
71}
72
73
74int NetworkGameManager::writeBytes(const byte* data, int length, int sender)
75{
76  int i = 0;
77  byte b;
78
79  while ( i<length )
80  {
81    b = data[i++];
82
83    /**************** Commands only processed by servers ****************/
84    if ( isServer() )
85    {
86      if ( b == NET_REQUEST_CREATE )
87      {
88        if ( !handleRequestCreate( i, data, length, sender ) )
89          return i;
90        continue;
91      }
92      else if ( b == NET_REQUEST_REMOVE )
93      {
94        if ( !handleRequestRemove( i, data, length, sender ) )
95          return i;
96        continue;
97      }
98      else if ( b == NET_REQUEST_PNODE_PATH )
99      {
100        if ( !handleRequestPNodePath( i, data, length, sender ) )
101          return i;
102        continue;
103      }
104    }
105    else
106    {
107      /**************** Commands only processed by clients ****************/
108      if ( b == NET_CREATE_ENTITY )
109      {
110        PRINTF(0)("CREATE_ENTITY\n");
111        if ( !handleCreateEntity( i, data, length, sender ) )
112          return i;
113        continue;
114      }
115      else if ( b == NET_REMOVE_ENTITY )
116      {
117        if ( !handleRemoveEntity( i, data, length, sender ) )
118          return i;
119        continue;
120      }
121      else if ( b == NET_CREATE_ENTITY_LIST )
122      {
123        if ( !handleCreateEntityList( i, data, length, sender ) )
124          return i;
125        continue;
126      }
127      else if ( b == NET_REMOVE_ENTITY_LIST )
128      {
129        if ( !handleRemoveEntityList( i, data, length, sender ) )
130          return i;
131        continue;
132      }
133      else if ( b == NET_YOU_ARE_ENTITY )
134      {
135        if ( !handleYouAreEntity( i, data, length, sender ) )
136          return i;
137        continue;
138      }
139    }
140
141    /**************** Commands processed by servers and clients ****************/
142    if ( b == NET_REQUEST_ENTITY_LIST )
143    {
144      sendEntityList( sender );
145      continue;
146    }
147    else if ( b == NET_REQUEST_SYNC )
148    {
149      if ( !handleRequestSync( i, data, length, sender ) )
150        return i;
151      continue;
152    }
153
154
155    PRINTF(1)("Network is asynchronous: couldn't decode the command sent by %i\n", sender);
156    PRINTF(1)("Probably this is because the network protocol has different \n");
157    PRINTF(1)("versions or there occured an error in the sending algorithm\n");
158    PRINTF(1)("Data is not in the right format! i=%d\n", i);
159    return i;
160  }
161
162  return i;
163}
164
165int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever)
166{
167  if ( !isServer() && !hasRequestedWorld )
168  {
169    assert( maxLength >= 1 );
170    data[0] = NET_REQUEST_ENTITY_LIST;
171    hasRequestedWorld = true;
172    return 1;
173  }
174
175  for ( int i = 0; i<outBuffer.size(); i++ )
176  {
177    *reciever = i;
178    if ( outBuffer[i].length>0 )
179    {
180      int nbytes = outBuffer[i].length;
181      outBuffer[i].length = 0;
182
183      if ( nbytes > maxLength )
184      {
185        PRINTF(1)("OutBuffer.length (%d) > (%d) networkStreamBuffer.maxLength\n", nbytes, maxLength);
186        return 0;
187      }
188
189      memcpy(data, outBuffer[i].buffer, nbytes);
190      return nbytes;
191    }
192  }
193
194  return 0;
195}
196
197void NetworkGameManager::writeDebug() const
198{
199}
200
201void NetworkGameManager::readDebug() const
202{
203}
204
205
206/*!
207 * Checks whether this is connected to a server or a client
208 * and afterwards creates the needed entity
209 * @param classID: The ID of the class of which an entity should be created
210 */
211int NetworkGameManager::createEntity( ClassID classID, int owner )
212{
213  if ( this->isServer())
214  {
215    if ( SharedNetworkData::getInstance()->getNewUniqueID() < 0 )
216    {
217      PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
218      return -1;
219    }
220    return this->executeCreateEntity( classID, SharedNetworkData::getInstance()->getNewUniqueID(), owner );
221  }
222  else
223  {
224    this->requestCreateEntity( classID );
225    return -1;
226  }
227}
228
229
230/*!
231 * Checks whether this is connected to a server or a client
232 * and afterwards creates the needed entity
233 * @param classID: The ID of the class of which an entity should be created
234 */
235BaseObject* NetworkGameManager::createEntity(const TiXmlElement* element)
236{
237  if ( this->isServer() )
238  {
239    if ( SharedNetworkData::getInstance()->getNewUniqueID() < 0 )
240    {
241      PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
242      return NULL;
243    }
244
245    BaseObject * b = Factory::fabricate( element );
246
247    if ( !b )
248    {
249      PRINTF(1)("Could not fabricate Object with className %s\n", element->Value() );
250      return NULL;
251    }
252
253
254    if ( b->isA(CL_SYNCHRONIZEABLE) )
255    {
256      Synchronizeable * s = dynamic_cast<Synchronizeable*>(b);
257      s->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
258      s->setOwner( 0 );
259      // all entities created via this function are added automaticaly to the synchronizeable list
260      s->setSynchronized(true);
261      return b;
262    }
263    else
264    {
265      PRINTF(1)("Class %s is not a synchronizeable!\n", b->getClassName() );
266      delete b;
267    }
268
269  }
270  else
271
272  {
273    PRINTF(1)("This node is not a server and cannot create id %x\n", element->Value());
274  }
275  return NULL;
276}
277
278
279/*!
280 * Checks whether this is connected to a server or a client
281 * and afterwards removes the specified entity
282 * @param uniqueID: The ID of the entity object which should be removed
283 */
284void NetworkGameManager::removeEntity(int uniqueID)
285{
286  if ( this->isServer() )
287  {
288    this->executeRemoveEntity( uniqueID );
289  }
290  else
291  {
292    this->requestRemoveEntity( uniqueID );
293  }
294}
295
296
297
298/*!
299 * Creates the needed entity on the server if possible
300 * @param classID: The ID of the class of which an entity should be created
301 */
302void NetworkGameManager::requestCreateEntity(ClassID classID)
303{
304  for ( int i = 0; i<outBuffer.size(); i++)
305  {
306    if ( !this->networkStream->isUserIdActive( i ) )
307      continue;
308
309    if ( !writeToClientBuffer( outBuffer[i], (byte)NET_REQUEST_CREATE ) )
310      return;
311    if ( !writeToClientBuffer( outBuffer[i], (int)classID ) )
312      return;
313  }
314}
315
316/*!
317 * Removes the specified entity on the server
318 * @param uniqueID: The ID of the entity object which should be removed
319 */
320void NetworkGameManager::requestRemoveEntity(int uniqueID)
321{
322  for ( int i = 0; i<outBuffer.size(); i++)
323  {
324    if ( !this->networkStream->isUserIdActive( i ) )
325      continue;
326
327    if ( !writeToClientBuffer( outBuffer[i], (byte)NET_REQUEST_REMOVE ) )
328      return;
329    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
330      return;
331  }
332}
333
334/*!
335 * Creates the needed entity if possible
336 * This function is called if this is a server
337 * @param classID: The ID of the class of which an entity should be created
338 */
339int NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner)
340{
341  for ( int i = 0; i<outBuffer.size(); i++)
342  {
343    if ( !this->networkStream->isUserIdActive( i ) )
344      continue;
345
346    if ( !writeToClientBuffer( outBuffer[i], (byte)NET_CREATE_ENTITY ) )
347      return -1;
348    if ( !writeToClientBuffer( outBuffer[i], (int)classID ) )
349      return -1;
350    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
351      return -1;
352    if ( !writeToClientBuffer( outBuffer[i], owner ) )
353      return -1;
354  }
355
356  PRINTF(0)("ExecuteCreateEntity: server side: classID: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner);
357  doCreateEntity( classID, uniqueID, owner );
358
359  return uniqueID;
360}
361
362/*!
363 * Removes the specified entity
364 * This function is called if this is a server
365 * @param uniqueID: The ID of the entity object which should be removed
366 */
367void NetworkGameManager::executeRemoveEntity(int uniqueID)
368{
369  for ( int i = 0; i<outBuffer.size(); i++)
370  {
371    if ( !this->networkStream->isUserIdActive( i ) )
372      continue;
373
374    if ( !writeToClientBuffer( outBuffer[i], (byte)NET_REMOVE_ENTITY ) )
375      return;
376    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
377      return;
378  }
379
380  doRemoveEntity(uniqueID);
381}
382
383/*!
384 * Checks whether it is possible to create an entity of a given class
385 * @return: true if the entity can be created, false otherwise
386 */
387bool NetworkGameManager::canCreateEntity(ClassID classID)
388{
389  return true;
390}
391
392/*!
393 * Sends the Entities to the new connected client
394 * @param userID: The ID of the user
395 */
396void NetworkGameManager::sendEntityList( int userID )
397{
398  if ( !isServer() )
399    return;
400
401  if ( userID >= outBuffer.size() )
402    resizeBufferVector( userID );
403
404  SynchronizeableList::const_iterator it, e;
405
406  it = this->networkStream->getSyncBegin();
407  e = this->networkStream->getSyncEnd();
408
409  // send the packet header
410  if ( !writeToClientBuffer( outBuffer[userID], (byte)NET_CREATE_ENTITY_LIST ) )
411    return;
412
413  // send the number of entities: -2 because you must not send network_game_manager and handshake
414  if ( !writeToClientBuffer( outBuffer[userID], networkStream->getSyncCount() ) )
415    return;
416
417  //PRINTF(0)("SendEntityList: n = %d\n", networkStream->getSyncCount()-2 );
418
419  // first send the NullParent
420  if ( !writeToClientBuffer( outBuffer[userID], (int)PNode::getNullParent()->getLeafClassID()) )
421    return;
422  if ( !writeToClientBuffer( outBuffer[userID], (int)PNode::getNullParent()->getUniqueID()) )
423    return;
424  if ( !writeToClientBuffer( outBuffer[userID], (int)PNode::getNullParent()->getOwner()) )
425    return;
426
427  // now send the rest of the entities
428  while ( it != e )
429  {
430    if( (*it)->beSynchronized() && (*it) != PNode::getNullParent())
431    {
432      PRINTF(0)("SENDING ENTITY %s classid: %x, uniqueid %d\n", (*it)->getClassName(), (*it)->getLeafClassID(), (*it)->getUniqueID() );
433      if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getLeafClassID()) ) )
434        return;
435
436      if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getUniqueID()) ) )
437        return;
438
439      if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getOwner()) ) )
440        return;
441    }
442    it++;
443  }
444
445  signalNewPlayer( userID );
446}
447
448
449
450bool NetworkGameManager::signalNewPlayer(int userId)
451{
452  if ( userId >= outBuffer.size() )
453    resizeBufferVector( userId );
454
455  /* create new playable for Player*/
456  PRINTF(0)("Request for creation: %i\n", userId);
457  int uniqueId = this->createEntity(CL_SPACE_SHIP, userId);
458  PRINTF(0)("Request for creation: userid: %i, uniqueid: %i\n", userId, uniqueId);
459  this->sendYouAre(uniqueId, userId);
460
461}
462
463
464
465bool NetworkGameManager::signalLeftPlayer(int userID)
466{
467  const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
468  std::list<BaseObject*>::const_iterator it = playableList->begin();
469
470  for(; it != playableList->end(); it++)
471  {
472    if( dynamic_cast<Synchronizeable*>(*it)->getOwner() == userID )
473    {
474      PRINTF(0)("remove playable from %i\n", userID);
475      this->removeEntity(dynamic_cast<Synchronizeable*>(*it)->getUniqueID());
476      return true;
477    }
478  }
479  return false;
480}
481
482
483/**
484 * Creates a buffer for user n
485 * @param n The ID of the user
486 */
487void NetworkGameManager::resizeBufferVector( int n )
488{
489  for ( int i = outBuffer.size(); i<=n; i++)
490  {
491    clientBuffer outBuf;
492
493    outBuf.length = 0;
494
495    outBuf.maxLength = 5*1024;
496
497    outBuf.buffer = new byte[5*1014];
498
499    outBuffer.push_back(outBuf);
500  }
501}
502
503/**
504 * Creates the entity on this host
505 * @param classID: ClassID of the entity to create
506 * @param uniqueID: Unique ID to assign to the synchronizeable
507 * @param owner: owner of this synchronizealbe
508 */
509BaseObject* NetworkGameManager::doCreateEntity( ClassID classID, int uniqueID, int owner )
510{
511  PRINTF(0)("Creating Entity via Factory: classid: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner);
512
513  BaseObject * b;
514  /* These are some small exeptions in creation: Not all objects can/should be created via Factory */
515  /* Exception 1: NullParent */
516  if( classID == CL_NULL_PARENT)
517  {
518    b = (BaseObject*)PNode::getNullParent();
519  }
520  else
521    b = Factory::fabricate( classID );
522
523  if ( !b )
524  {
525    PRINTF(1)("Could not fabricate Object with classID %x\n", classID);
526    return NULL;
527  }
528
529  if ( b->isA(CL_SYNCHRONIZEABLE) )
530  {
531    Synchronizeable * s = dynamic_cast<Synchronizeable*>(b);
532    s->setUniqueID( uniqueID );
533    s->setOwner( owner );
534    s->setSynchronized(true);
535    //this->networkStream->connectSynchronizeable( *s );
536    if ( !isServer() )
537      s->setIsOutOfSync( true );
538    PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID());
539
540    //HACK: hack to prevent collision
541    if ( b->isA(CL_WORLD_ENTITY) && !b->isA(CL_PLAYABLE) )
542    {
543      if ( SharedNetworkData::getInstance()->getHostID()!=0 )
544      {
545        static Vector pos = Vector(1000.0, 1000.0, 1000.0);
546        PNode *p = dynamic_cast<PNode*>(b);
547        p->setAbsCoor(pos);
548        p->updateNode(0);
549        pos += Vector(1000.0, 1000.0, 1000.0);
550      }
551    }
552
553    return b;
554  }
555  else
556  {
557    PRINTF(1)("Class with ID %x is not a synchronizeable!", (int)classID);
558    delete b;
559  }
560  return NULL;
561}
562
563/**
564 * Removes a entity on this host
565 * @param uniqueID: unique ID assigned with the entity to remove
566 */
567void NetworkGameManager::doRemoveEntity( int uniqueID )
568{
569  SynchronizeableList::const_iterator it,e;
570  it = this->networkStream->getSyncBegin();
571  e = this->networkStream->getSyncEnd();
572
573  while ( it != e )
574  {
575    if ( (*it)->getUniqueID() == uniqueID )
576    {
577      assert((*it)->isA(CL_WORLD_ENTITY));
578      dynamic_cast<WorldEntity*>(*it)->leaveWorld();
579      dynamic_cast<WorldEntity*>(*it)->toList(OM_DEAD);
580      break;
581    }
582    it++;
583  }
584}
585
586/**
587 * Tell the synchronizeable that a user's synchronizeable is out of sync
588 * @param uniqueID: unique ID assigned with the entity which is out of sync
589 * @param userID: user ID who's synchronizeable is out of sync
590 */
591void NetworkGameManager::doRequestSync( int uniqueID, int userID )
592{
593  SynchronizeableList::const_iterator it,e;
594  it = this->networkStream->getSyncBegin();
595  e = this->networkStream->getSyncEnd();
596
597  while ( it != e )
598  {
599    if ( (*it)->getUniqueID() == uniqueID )
600    {
601      (*it)->requestSync( userID );
602      break;
603    }
604    it++;
605  }
606}
607
608/**
609 * Copies length bytes to the clientBuffer with error checking
610 * @param clientBuffer: the clientBuffer to write to
611 * @param data: buffer to the data
612 * @param length: length of data
613 * @return false on error true else
614 */
615bool NetworkGameManager::writeToClientBuffer( clientBuffer &cb, byte * data, int length )
616{
617  if ( length > cb.maxLength-cb.length )
618  {
619    PRINTF(1)("No space left in clientBuffer\n");
620    return false;
621  }
622
623  memcpy( cb.buffer+cb.length, data, length );
624  return true;
625}
626
627/**
628 * Reads data from clientBuffer with error checking
629 * @param clientBuffer: the clientBuffer to read from
630 * @param data: pointer to the buffer
631 * @param length:
632 * @return
633 */
634bool NetworkGameManager::readFromClientBuffer( clientBuffer &cb, byte * data, int length )
635{
636  if ( cb.length < length )
637  {
638    PRINTF(0)("There is not enough data in clientBuffer\n");
639    return 0;
640  }
641
642  memcpy( data, cb.buffer+cb.length-length, length );
643  return true;
644}
645
646/**
647 * Tells this client that he has to control this entity
648 * @param uniqueID: the entity's uniqeID
649 */
650void NetworkGameManager::doYouAre( int uniqueID )
651{
652
653  SynchronizeableList::const_iterator it = this->networkStream->getSyncBegin();
654
655  Playable *p = NULL;
656  Synchronizeable *s = NULL;
657
658  for ( ; it !=networkStream->getSyncEnd(); it++ )
659  {
660    if ( (*it)->getUniqueID()==uniqueID )
661    {
662      if ( (*it)->isA( CL_SYNCHRONIZEABLE ) )
663      {
664        s = dynamic_cast<Synchronizeable*>(*it);
665      }
666      if ( (*it)->isA( CL_PLAYABLE ) )
667      {
668        p = dynamic_cast<Playable*>(*it);
669        break;
670      } else
671      {
672        PRINTF(1)("UniqueID is not a Playable\n");
673      }
674    }
675  }
676
677  Player* player = State::getPlayer();
678  assert(p != NULL);
679  assert(s != NULL);
680  assert(player != NULL);
681
682  s->setIsOutOfSync( true );
683
684  PRINTF(0)("uniqueID = %d\n", s->getUniqueID());
685
686  player->setControllable(p);
687
688
689}
690
691/**
692 * Tells a remote client that he has to control this entity
693 * @param uniqueID: the entity's uniqeID
694 * @param userID: the users ID
695 */
696void NetworkGameManager::sendYouAre( int uniqueID, int userID )
697{
698  if ( !isServer() )
699    return;
700
701  if ( userID != 0 )
702  {
703    if ( !writeToClientBuffer( outBuffer[userID], (byte)NET_YOU_ARE_ENTITY ) )
704      return;
705
706    if ( !writeToClientBuffer( outBuffer[userID], uniqueID ) )
707      return;
708  }
709  else
710  {
711    doYouAre(uniqueID);
712  }
713}
714
715bool NetworkGameManager::handleRequestCreate( int & i, const byte * data, int length, int sender )
716{
717  if ( INTSIZE > length-i )
718  {
719    PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
720    return false;
721  }
722  int classID;
723  i += Converter::byteArrayToInt( &data[i], &classID );
724
725  createEntity( (ClassID)classID );
726
727  return true;
728}
729
730bool NetworkGameManager::handleRequestRemove( int & i, const byte * data, int length, int sender )
731{
732  if ( INTSIZE > length-i )
733  {
734    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
735    return false;
736  }
737  int uniqueID;
738  i += Converter::byteArrayToInt( &data[i], &uniqueID );
739
740  removeEntity( uniqueID );
741
742  return true;
743}
744
745bool NetworkGameManager::handleCreateEntity( int & i, const byte * data, int length, int sender )
746{
747  if ( INTSIZE > length-i )
748  {
749    PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
750    return false;
751  }
752  int classID;
753  i += Converter::byteArrayToInt( &data[i], &classID );
754
755  if ( INTSIZE > length-i )
756  {
757    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
758    return false;
759  }
760  int uniqueID;
761  i += Converter::byteArrayToInt( &data[i], &uniqueID );
762
763  if ( INTSIZE > length-i )
764  {
765    PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n");
766    return false;
767  }
768  int owner;
769  i += Converter::byteArrayToInt( &data[i], &owner );
770
771  PRINTF(0)("handleCreateEntity: client side: classID: %x, uniqueID: %i, owner: %i\n", classID, uniqueID, owner);
772  doCreateEntity( (ClassID)classID, uniqueID, owner );
773
774  return true;
775}
776
777bool NetworkGameManager::handleRemoveEntity( int & i, const byte * data, int length, int sender )
778{
779  if ( INTSIZE > length-i )
780  {
781    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
782    return false;
783  }
784  int uniqueID;
785  i += Converter::byteArrayToInt( &data[i], &uniqueID );
786
787  doRemoveEntity( uniqueID );
788
789  return true;
790}
791
792bool NetworkGameManager::handleCreateEntityList( int & i, const byte * data, int length, int sender )
793{
794  if ( INTSIZE > length-i )
795  {
796    PRINTF(1)("Cannot read n from buffer! Not enough data left!\n");
797    return false;
798  }
799
800  PRINTF(0)("HandleCreateEntityList:  data[i..i+3] = %d %d %d %d\n", data[i], data[i+1], data[i+2], data[i+3]);
801
802  int n;
803  i += Converter::byteArrayToInt( &data[i], &n );
804
805
806  PRINTF(0)("HandleCreateEntityList: n = %d\n", n);
807
808  int classID, uniqueID, owner;
809
810  for ( int j = 0; j<n; j++ )
811  {
812
813    if ( INTSIZE > length-i )
814    {
815      PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
816      return false;
817    }
818    i += Converter::byteArrayToInt( &data[i], &classID );
819
820    if ( INTSIZE > length-i )
821    {
822      PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
823      return false;
824    }
825    i += Converter::byteArrayToInt( &data[i], &uniqueID );
826
827    if ( INTSIZE > length-i )
828    {
829      PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n");
830      return false;
831    }
832    i += Converter::byteArrayToInt( &data[i], &owner );
833
834    if ( classID != CL_NETWORK_GAME_MANAGER && classID != CL_HANDSHAKE )
835    {
836      BaseObject* b = doCreateEntity( (ClassID)classID, uniqueID, owner );
837    }
838
839  }
840
841  return true;
842}
843
844bool NetworkGameManager::handleRemoveEntityList( int & i, const byte * data, int length, int sender )
845{
846  if ( INTSIZE > length-i )
847  {
848    PRINTF(1)("Cannot read n from buffer! Not enough data left!\n");
849    return false;
850  }
851  int n;
852  i += Converter::byteArrayToInt( &data[i], &n );
853
854  int uniqueID;
855
856  for ( int j = 0; j<n; j++ )
857  {
858
859    if ( INTSIZE > length-i )
860    {
861      PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
862      return false;
863    }
864    i += Converter::byteArrayToInt( &data[i], &uniqueID );
865
866    doRemoveEntity( uniqueID );
867  }
868
869  return true;
870}
871
872bool NetworkGameManager::handleYouAreEntity( int & i, const byte * data, int length, int sender )
873{
874  if ( INTSIZE > length-i )
875  {
876    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
877    return false;
878  }
879
880  int uniqueID;
881  i += Converter::byteArrayToInt( &data[i], &uniqueID );
882
883  doYouAre( uniqueID );
884
885  return true;
886}
887
888bool NetworkGameManager::handleRequestSync( int & i, const byte * data, int length, int sender )
889{
890  if ( INTSIZE > length-i )
891  {
892    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
893    return false;
894  }
895  int uniqueID;
896  i += Converter::byteArrayToInt( &data[i], &uniqueID );
897
898  PRINTF(0)("handleRequestSync %d %d\n", uniqueID, sender);
899  doRequestSync( uniqueID, sender );
900
901  return true;
902}
903
904
905/**
906 *  handles the network signal NET_REQUEST_PNODE_PATH
907 * @param i byte offset in the buffer
908 * @param data data array
909 * @param length length of the data arary
910 * @param sender the sender id
911 * @return true if process terminated sucessfully
912 */
913bool NetworkGameManager::handleRequestPNodePath(int& i, const byte* data, int length, int sender)
914{
915  if( INTSIZE > length-i )
916  {
917    PRINTF(1)("Cannot read n from buffer! Not enough data left!\n");
918    return false;
919  }
920  PRINTF(0)("HandleRequestPNodePath:  data[i..i+3] = %d %d %d %d\n", data[i], data[i+1], data[i+2], data[i+3]);
921
922  int uniqueID1, uniqueID2;
923  if( INTSIZE > length-i )
924  {
925    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
926    return false;
927  }
928  i += Converter::byteArrayToInt( &data[i], &uniqueID1 );
929
930  if( INTSIZE > length-i )
931  {
932    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
933    return false;
934  }
935  i += Converter::byteArrayToInt( &data[i], &uniqueID2 );
936
937
938  PRINTF(0)("HandleRequestPNodePath: got a request for path from uid %i to uid %i\n", uniqueID1, uniqueID2);
939
940  return true;
941}
942
943
944bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b )
945{
946  if ( cb.maxLength-cb.length < 1 )
947  {
948    PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 byte\n");
949    return false;
950  }
951
952  cb.buffer[cb.length++] = b;
953
954  return true;
955}
956
957bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i )
958{
959  int n = Converter::intToByteArray( i, cb.buffer+cb.length, cb.maxLength-cb.length );
960  cb.length += n;
961
962  if ( n <= 0 )
963  {
964    PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 int\n");
965    return false;
966  }
967
968  return true;
969}
970
971void NetworkGameManager::sync( int uniqueID, int owner )
972{
973  /*if ( owner==this->getHostID() )
974  return;*/
975
976  if ( !isServer() )
977    executeRequestSync( uniqueID, 0 );
978  else
979    executeRequestSync( uniqueID, owner );
980}
981
982void NetworkGameManager::executeRequestSync( int uniqueID, int user )
983{
984  PRINTF(0)("executeRequestSync %d %d\n", uniqueID, user);
985  if ( user >= outBuffer.size() )
986    resizeBufferVector( user );
987
988  if ( !writeToClientBuffer( outBuffer[user], (byte)NET_REQUEST_SYNC ) )
989    return;
990  if ( !writeToClientBuffer( outBuffer[user], uniqueID ) )
991    return;
992}
993
Note: See TracBrowser for help on using the repository browser.