Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

network: restructured the writeBytes a little bit and added the new functions

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