Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: new style for resources (prework/movement)

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