Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/network/network_stream.cc @ 8932

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

orxonox/trunk: merged the network branche back here
merged with command:
svn merge -r8230:HEAD https://svn.orxonox.net/orxonox/branches/network .
conflicts resolved in favour of the network branche (conflicts were in network)

File size: 22.2 KB
RevLine 
[5566]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:
[5601]12   main-programmer: claudio
[5800]13   co-programmer:
[5566]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
[5747]22
[5647]23#include "base_object.h"
[5731]24#include "network_protocol.h"
[7954]25#include "udp_socket.h"
26#include "udp_server_socket.h"
[5647]27#include "connection_monitor.h"
28#include "synchronizeable.h"
[6341]29#include "network_game_manager.h"
[6959]30#include "shared_network_data.h"
[7954]31#include "message_manager.h"
32#include "preferences.h"
33#include "zip.h"
[6341]34
[7954]35#include "src/lib/util/loading/resource_manager.h"
36
37#include "network_log.h"
38
39
40#include "lib/util/loading/factory.h"
41
[5649]42#include "debug.h"
[6139]43#include "class_list.h"
[6144]44#include <algorithm>
[5647]45
[5566]46/* include your own header */
47#include "network_stream.h"
48
[5595]49/* probably unnecessary */
[5594]50using namespace std;
51
[5595]52
[5747]53#define PACKAGE_SIZE  256
[5647]54
[5747]55
[5800]56NetworkStream::NetworkStream()
[5996]57    : DataStream()
[5647]58{
59  this->init();
[5648]60  /* initialize the references */
[5996]61  this->type = NET_CLIENT;
[5647]62}
63
[6695]64
[7954]65NetworkStream::NetworkStream( std::string host, int port )
[5996]66{
[6139]67  this->type = NET_CLIENT;
[5996]68  this->init();
[7954]69  this->peers[0].socket = new UdpSocket( host, port );
70  this->peers[0].userId = 0;
71  this->peers[0].isServer = true;
72  this->peers[0].connectionMonitor = new ConnectionMonitor( 0 );
[5996]73}
74
75
[7954]76NetworkStream::NetworkStream( int port )
[5647]77{
[6139]78  this->type = NET_SERVER;
[5647]79  this->init();
[7954]80  this->serverSocket = new UdpServerSocket(port);
[5996]81  this->bActive = true;
[5649]82}
83
84
[5647]85void NetworkStream::init()
86{
87  /* set the class id for the base object */
88  this->setClassID(CL_NETWORK_STREAM, "NetworkStream");
[5996]89  this->bActive = false;
[6139]90  this->serverSocket = NULL;
[6341]91  this->networkGameManager = NULL;
[6139]92  myHostId = 0;
[7954]93  currentState = 0;
94 
95  remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
96 
[8623]97  assert( Zip::getInstance()->loadDictionary( "testdict" ) >= 0 );
98  this->dictClient = Zip::getInstance()->loadDictionary( "dict2pl_client" );
99  assert( this->dictClient >= 0 );
100  this->dictServer = Zip::getInstance()->loadDictionary( "dict2p_server" );
101  assert( this->dictServer >= 0 );
[5594]102}
103
[5647]104
[5566]105NetworkStream::~NetworkStream()
[5598]106{
[6139]107  if ( this->serverSocket )
108  {
109    serverSocket->close();
110    delete serverSocket;
[8228]111    serverSocket = NULL;
[6139]112  }
[5723]113
[7954]114  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
[6139]115  {
[7954]116    if ( i->second.socket )
[6139]117    {
[7954]118      i->second.socket->disconnectServer();
119      delete i->second.socket;
120      i->second.socket = NULL;
[6139]121    }
[7954]122   
123    if ( i->second.handshake )
[6139]124    {
[7954]125      delete i->second.handshake;
126      i->second.handshake = NULL;
[6139]127    }
[8623]128   
129    if ( i->second.connectionMonitor )
130    {
131      delete i->second.connectionMonitor;
132      i->second.connectionMonitor = NULL;
133    }
[6139]134  }
[7954]135 
[8228]136  for ( SynchronizeableList::const_iterator it = getSyncBegin(); it != getSyncEnd(); it ++ )
137    (*it)->setNetworkStream( NULL );
[5598]138}
139
[5996]140
[6695]141void NetworkStream::createNetworkGameManager()
142{
143  this->networkGameManager = NetworkGameManager::getInstance();
144  // setUniqueID( maxCon+2 ) because we need one id for every handshake
145  // and one for handshake to reject client maxCon+1
[7954]146  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
147  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
[6695]148}
149
150
151void NetworkStream::startHandshake()
152{
153  Handshake* hs = new Handshake(false);
154  hs->setUniqueID( 0 );
[7954]155  assert( peers[0].handshake == NULL );
156  peers[0].handshake = hs;
157//   peers[0].handshake->setSynchronized( true );
[6695]158  //this->connectSynchronizeable(*hs);
[7954]159  //this->connectSynchronizeable(*hs);
160  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getName());
[6695]161}
162
163
[5996]164void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
165{
[6139]166  this->synchronizeables.push_back(&sync);
167  sync.setNetworkStream( this );
168
[7954]169  this->bActive = true;
[5996]170}
171
[6695]172
[6139]173void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync)
174{
[6144]175  // removing the Synchronizeable from the List.
176  std::list<Synchronizeable*>::iterator disconnectSynchro = std::find(this->synchronizeables.begin(), this->synchronizeables.end(), &sync);
177  if (disconnectSynchro != this->synchronizeables.end())
178    this->synchronizeables.erase(disconnectSynchro);
[7954]179 
180  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
[6139]181}
182
183
[5604]184void NetworkStream::processData()
185{
[8068]186  int tick = SDL_GetTicks();
187 
[7954]188  currentState++;
189 
[6139]190  if ( this->type == NET_SERVER )
[7954]191  {
192    if ( serverSocket )
193      serverSocket->update();
194   
[6139]195    this->updateConnectionList();
[7954]196  }
[6139]197  else
198  {
[7954]199    if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) )
[6139]200    {
201      PRINTF(1)("lost connection to server\n");
[5741]202
[7954]203      peers[0].socket->disconnectServer();
204      delete peers[0].socket;
205      peers[0].socket = NULL;
[6498]206
[7954]207      if ( peers[0].handshake )
208        delete peers[0].handshake;
209      peers[0].handshake = NULL;
[8623]210     
211      if ( peers[0].connectionMonitor )
212        delete peers[0].connectionMonitor;
213      peers[0].connectionMonitor = NULL;
[6139]214    }
215  }
216
[7954]217  cleanUpOldSyncList();
218  handleHandshakes();
219 
220  // order of up/downstream is important!!!!
221  // don't change it
[8068]222  handleDownstream( tick );
223  handleUpstream( tick );
[7954]224
225}
226
227void NetworkStream::updateConnectionList( )
228{
229  //check for new connections
230
231  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
232
233  if ( tempNetworkSocket )
[6139]234  {
[7954]235    int clientId;
236    if ( freeSocketSlots.size() >0 )
[6139]237    {
[7954]238      clientId = freeSocketSlots.back();
239      freeSocketSlots.pop_back();
240      peers[clientId].socket = tempNetworkSocket;
241      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID() );
242      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
243      peers[clientId].handshake->setUniqueID(clientId);
244      peers[clientId].userId = clientId;
245      peers[clientId].isServer = false;
246    } else
247    {
248      clientId = 1;
249     
250      for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
251        if ( it->first >= clientId )
252          clientId = it->first + 1;
253     
254      peers[clientId].socket = tempNetworkSocket;
255      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
256      peers[clientId].handshake->setUniqueID(clientId);
257      peers[clientId].connectionMonitor = new ConnectionMonitor( clientId );
258      peers[clientId].userId = clientId;
259      peers[clientId].isServer = false;
260     
261      PRINTF(0)("num sync: %d\n", synchronizeables.size());
262    }
[6341]263
[7954]264    if ( clientId > MAX_CONNECTIONS )
265    {
266      peers[clientId].handshake->doReject( "too many connections" );
267      PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
268    }
269    else
[6498]270
[7954]271    PRINTF(0)("New Client: %d\n", clientId);
[6341]272
[7954]273    //this->connectSynchronizeable(*handshakes[clientId]);
274  }
[6341]275
[7954]276  //check if connections are ok else remove them
[8228]277  for ( PeerList::iterator it = peers.begin(); it != peers.end(); )
[7954]278  {
279    if ( 
280          it->second.socket &&
281          ( 
282            !it->second.socket->isOk()  ||
283            it->second.connectionMonitor->hasTimedOut()
284          )
285       )
286    {
287      std::string reason = "disconnected";
288      if ( it->second.connectionMonitor->hasTimedOut() )
289        reason = "timeout";
290      PRINTF(0)("Client is gone: %d (%s)\n", it->second.userId, reason.c_str());
291     
[8068]292      //assert(false);
[7954]293
294      it->second.socket->disconnectServer();
295      delete it->second.socket;
296      it->second.socket = NULL;
297
[8623]298      if ( it->second.connectionMonitor )
299        delete it->second.connectionMonitor;
300      it->second.connectionMonitor = NULL;
301     
[7954]302      if ( it->second.handshake )
303        delete it->second.handshake;
304      it->second.handshake = NULL;
305     
306      for ( SynchronizeableList::iterator it2 = synchronizeables.begin(); it2 != synchronizeables.end(); it2++ )
307      {
308        (*it2)->cleanUpUser( it->second.userId );
[6139]309      }
[7954]310
311      NetworkGameManager::getInstance()->signalLeftPlayer(it->second.userId);
312
313      freeSocketSlots.push_back( it->second.userId );
[8228]314     
315      PeerList::iterator delit = it;
316      it++;
317     
318      peers.erase( delit );
319     
320      continue;
[6139]321    }
[8228]322   
323    it++;
[6139]324  }
325
326
[7954]327}
[5800]328
[7954]329void NetworkStream::debug()
330{
331  if( this->isServer())
332    PRINT(0)(" Host ist Server with ID: %i\n", this->myHostId);
333  else
334    PRINT(0)(" Host ist Client with ID: %i\n", this->myHostId);
[6695]335
[7954]336  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
[6139]337  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
[5996]338  {
[7954]339    if( (*it)->beSynchronized() == true)
340      PRINT(0)("  Synchronizeable of class: %s::%s, with unique ID: %i, Synchronize: %i\n", (*it)->getClassName(), (*it)->getName(),
341               (*it)->getUniqueID(), (*it)->beSynchronized());
342  }
343  PRINT(0)(" Maximal Connections: %i\n", MAX_CONNECTIONS );
[6959]344
[7954]345}
[6959]346
347
[7954]348int NetworkStream::getSyncCount()
349{
350  int n = 0;
351  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
352    if( (*it)->beSynchronized() == true)
353      ++n;
[5730]354
[7954]355  //return synchronizeables.size();
356  return n;
357}
[6139]358
[7954]359/**
360 * check if handshakes completed
361 */
362void NetworkStream::handleHandshakes( )
363{
364  for ( PeerList::iterator it = peers.begin(); it != peers.end(); it++ )
365  {
366    if ( it->second.handshake )
367    {
368      if ( it->second.handshake->completed() )
369      {
370        if ( it->second.handshake->ok() )
[6341]371        {
[7954]372          if ( !it->second.handshake->allowDel() )
[6139]373          {
[7954]374            if ( type != NET_SERVER )
[6868]375            {
[7954]376              SharedNetworkData::getInstance()->setHostID( it->second.handshake->getHostId() );
377              myHostId = SharedNetworkData::getInstance()->getHostID();
378
379              this->networkGameManager = NetworkGameManager::getInstance();
380              this->networkGameManager->setUniqueID( it->second.handshake->getNetworkGameManagerId() );
381              MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() );
[6868]382            }
[7954]383             
384
385            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
386
387            it->second.handshake->del();
[6139]388          }
389          else
390          {
[7954]391            if ( it->second.handshake->canDel() )
[6868]392            {
[7954]393              if ( type == NET_SERVER )
394              {
395                handleNewClient( it->second.userId );
396              }
397             
398              PRINT(0)("handshake finished delete it\n");
399              delete it->second.handshake;
400              it->second.handshake = NULL;
[6868]401            }
[6139]402          }
[7954]403
[6139]404        }
405        else
406        {
[7954]407          PRINT(1)("handshake failed!\n");
408          it->second.socket->disconnectServer();
[6139]409        }
[7954]410      }
[6139]411    }
[5996]412  }
[7954]413}
[5741]414
[7954]415/**
416 * handle upstream network traffic
417 */
[8068]418void NetworkStream::handleUpstream( int tick )
[7954]419{
420  int offset;
421  int n;
422 
[8068]423  for ( PeerList::reverse_iterator peer = peers.rbegin(); peer != peers.rend(); peer++ )
[5802]424  {
[7954]425    offset = INTSIZE; //make already space for length
426   
427    if ( !peer->second.socket )
428      continue;
429   
430    n = Converter::intToByteArray( currentState, buf + offset, UDP_PACKET_SIZE - offset );
431    assert( n == INTSIZE );
432    offset += n;
433   
434    n = Converter::intToByteArray( peer->second.lastAckedState, buf + offset, UDP_PACKET_SIZE - offset );
435    assert( n == INTSIZE );
436    offset += n;
437   
438    n = Converter::intToByteArray( peer->second.lastRecvedState, buf + offset, UDP_PACKET_SIZE - offset );
439    assert( n == INTSIZE );
440    offset += n;
441   
442    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
[5810]443    {
[7954]444      int oldOffset = offset;
445      Synchronizeable & sync = **it;
446     
447      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
448        continue;
[5730]449
[7954]450      //if handshake not finished only sync handshake
451      if ( peer->second.handshake && sync.getLeafClassID() != CL_HANDSHAKE )
452        continue;
453     
454      if ( isServer() && sync.getLeafClassID() == CL_HANDSHAKE && sync.getUniqueID() != peer->second.userId )
455        continue;
456     
457      //do not sync null parent
458      if ( sync.getLeafClassID() == CL_NULL_PARENT )
459        continue;
[6139]460
[7954]461      assert( offset + INTSIZE <= UDP_PACKET_SIZE );
462     
463      //server fakes uniqueid=0 for handshake
464      if ( this->isServer() && sync.getUniqueID() < MAX_CONNECTIONS - 1 )
465        n = Converter::intToByteArray( 0, buf + offset, UDP_PACKET_SIZE - offset );
466      else
467        n = Converter::intToByteArray( sync.getUniqueID(), buf + offset, UDP_PACKET_SIZE - offset );
468      assert( n == INTSIZE );
469      offset += n;
470     
471      //make space for size
472      offset += INTSIZE;
[6139]473
[7954]474      n = sync.getStateDiff( peer->second.userId, buf + offset, UDP_PACKET_SIZE-offset, currentState, peer->second.lastAckedState, -1000 );
475      offset += n;
476      //NETPRINTF(0)("GGGGGEEEEETTTTT: %s (%d) %d\n",sync.getClassName(), sync.getUniqueID(), n);
477     
478      assert( Converter::intToByteArray( n, buf + offset - n - INTSIZE, INTSIZE ) == INTSIZE );
479     
480      //check if all bytes == 0 -> remove data
481      //TODO not all synchronizeables like this maybe add Synchronizeable::canRemoveZeroDiff()
482      bool allZero = true; 
483      for ( int i = 0; i < n; i++ ) 
484      { 
485         if ( buf[i+oldOffset+2*INTSIZE] != 0 ) 
486           allZero = false; 
487      } 
[6341]488
[7954]489      if ( allZero ) 
490      { 
491        //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID());
492        offset = oldOffset; 
493      } 
[6139]494
[7954]495     
[5810]496    }
[7954]497   
498    for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
499    {
500      Synchronizeable & sync = **it;
501     
502      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
503        continue;
504     
505      sync.handleSentState( peer->second.userId, currentState, peer->second.lastAckedState );
506    }
507   
508    assert( Converter::intToByteArray( offset, buf, INTSIZE ) == INTSIZE );
509   
[8623]510    int compLength = 0;
511    if ( this->isServer() )
512      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictServer );
513    else
514      compLength = Zip::getInstance()->zip( buf, offset, compBuf, UDP_PACKET_SIZE, dictClient );
[7954]515   
[8623]516    if ( compLength <= 0 )
[7954]517    {
518      PRINTF(1)("compression failed!\n");
519      continue;
520    }
521   
522    assert( peer->second.socket->writePacket( compBuf, compLength ) );
523   
524    if ( this->remainingBytesToWriteToDict > 0 )
[8623]525      writeToNewDict( buf, offset, true );
[7954]526   
[8068]527    peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState );
528    peer->second.connectionMonitor->processZippedOutgoingPacket( tick, compBuf, compLength, currentState );
[7954]529   
530    //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId);
[5810]531  }
[6139]532}
533
[7954]534/**
535 * handle downstream network traffic
536 */
[8068]537void NetworkStream::handleDownstream( int tick )
[6139]538{
[7954]539  int offset = 0;
540 
541  int length = 0;
542  int packetLength = 0;
543  int compLength = 0;
544  int uniqueId = 0;
545  int state = 0;
546  int ackedState = 0;
547  int fromState = 0;
548  int syncDataLength = 0;
549 
550  for ( PeerList::iterator peer = peers.begin(); peer != peers.end(); peer++ )
[5810]551  {
[7954]552   
553    if ( !peer->second.socket )
554      continue;
[5730]555
[7954]556    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
[6139]557    {
[8068]558      peer->second.connectionMonitor->processZippedIncomingPacket( tick, compBuf, compLength );
559     
[7954]560      //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
561      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
[8623]562
[7954]563      if ( packetLength < 4*INTSIZE )
564      {
565        if ( packetLength != 0 )
566          PRINTF(1)("got too small packet: %d\n", packetLength);
567        continue;
568      }
569     
570      if ( this->remainingBytesToWriteToDict > 0 )
[8623]571        writeToNewDict( buf, packetLength, false );
[7954]572   
573      assert( Converter::byteArrayToInt( buf, &length ) == INTSIZE );
574      assert( Converter::byteArrayToInt( buf + INTSIZE, &state ) == INTSIZE );
575      assert( Converter::byteArrayToInt( buf + 2*INTSIZE, &fromState ) == INTSIZE );
576      assert( Converter::byteArrayToInt( buf + 3*INTSIZE, &ackedState ) == INTSIZE );
577      //NETPRINTF(n)("ackedstate: %d\n", ackedState);
578      offset = 4*INTSIZE;
[8068]579     
[8623]580      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState );
[6139]581
[7954]582      //NETPRINTF(n)("got packet: %d, %d\n", length, packetLength);
583   
584    //if this is an old state drop it
585      if ( state <= peer->second.lastRecvedState )
586        continue;
587   
588      if ( packetLength != length )
589      {
590        PRINTF(1)("real packet length (%d) and transmitted packet length (%d) do not match!\n", packetLength, length);
591        peer->second.socket->disconnectServer();
592        continue;
593      }
594     
595      while ( offset + 2*INTSIZE < length )
596      {
597        assert( offset > 0 );
598        assert( Converter::byteArrayToInt( buf + offset, &uniqueId ) == INTSIZE );
599        offset += INTSIZE;
600     
601        assert( Converter::byteArrayToInt( buf + offset, &syncDataLength ) == INTSIZE );
602        offset += INTSIZE;
603       
604        assert( syncDataLength > 0 );
605        assert( syncDataLength < 10000 );
606     
607        Synchronizeable * sync = NULL;
608       
609        for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
610        { 
611        //                                        client thinks his handshake has id 0!!!!!
612          if ( (*it)->getUniqueID() == uniqueId || ( uniqueId == 0 && (*it)->getUniqueID() == peer->second.userId ) )
613          {
614            sync = *it;
615            break;
616          }
617        }
618       
619        if ( sync == NULL )
620        {
621          PRINTF(0)("could not find sync with id %d. try to create it\n", uniqueId);
622          if ( oldSynchronizeables.find( uniqueId ) != oldSynchronizeables.end() )
623          {
624            offset += syncDataLength;
625            continue;
626          }
627         
628          if ( !peers[peer->second.userId].isServer )
629          {
630            offset += syncDataLength;
631            continue;
632          }
633         
634          int leafClassId;
635          if ( INTSIZE > length - offset )
636          {
637            offset += syncDataLength;
638            continue;
639          }
[6139]640
[7954]641          Converter::byteArrayToInt( buf + offset, &leafClassId );
642         
643          assert( leafClassId != 0 );
644       
645          BaseObject * b = NULL;
646          /* These are some small exeptions in creation: Not all objects can/should be created via Factory */
647          /* Exception 1: NullParent */
648          if( leafClassId == CL_NULL_PARENT || leafClassId == CL_SYNCHRONIZEABLE || leafClassId == CL_NETWORK_GAME_MANAGER )
649          {
650            PRINTF(1)("Can not create Class with ID %x!\n", (int)leafClassId);
651            offset += syncDataLength;
652            continue;
653          }
654          else
655            b = Factory::fabricate( (ClassID)leafClassId );
[5800]656
[7954]657          if ( !b )
658          {
659            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
660            offset += syncDataLength;
661            continue;
662          }
[5809]663
[7954]664          if ( b->isA(CL_SYNCHRONIZEABLE) )
665          {
666            sync = dynamic_cast<Synchronizeable*>(b);
667            sync->setUniqueID( uniqueId );
668            sync->setSynchronized(true);
669 
670            PRINTF(0)("Fabricated %s with id %d\n", sync->getClassName(), sync->getUniqueID());
671          }
672          else
673          {
674            PRINTF(1)("Class with ID %x is not a synchronizeable!\n", (int)leafClassId);
675            delete b;
676            offset += syncDataLength;
677            continue;
678          }
679        }
[8228]680       
[6139]681
[7954]682        int n = sync->setStateDiff( peer->second.userId, buf+offset, syncDataLength, state, fromState ); 
683        offset += n;
684        //NETPRINTF(0)("SSSSSEEEEETTTTT: %s %d\n",sync->getClassName(), n);
[6498]685
[7954]686      }
687     
688      if ( offset != length )
[6139]689      {
[7954]690        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
691        peer->second.socket->disconnectServer();
[6139]692      }
[7954]693     
694     
695      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
[6139]696      {
[7954]697        Synchronizeable & sync = **it;
698     
699        if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
700          continue;
701     
702        sync.handleRecvState( peer->second.userId, state, fromState );
[6139]703      }
[7954]704     
705      assert( peer->second.lastAckedState <= ackedState );
706      peer->second.lastAckedState = ackedState;
707     
708      assert( peer->second.lastRecvedState < state );
709      peer->second.lastRecvedState = state;
[8228]710
[6139]711    }
[7954]712 
[6139]713  }
[7954]714 
715}
[6139]716
[7954]717/**
718 * is executed when a handshake has finished
719 * @todo create playable for new user
720 */
721void NetworkStream::handleNewClient( int userId )
722{
723  MessageManager::getInstance()->initUser( userId );
724 
725  networkGameManager->signalNewPlayer( userId );
[5604]726}
[6139]727
[7954]728/**
729 * removes old items from oldSynchronizeables
730 */
731void NetworkStream::cleanUpOldSyncList( )
[6139]732{
[7954]733  int now = SDL_GetTicks();
734 
735  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
[6139]736  {
[7954]737    if ( it->second < now - 10*1000 )
738    {
739      std::map<int,int>::iterator delIt = it;
740      it++;
741      oldSynchronizeables.erase( delIt );
742      continue;
743    }
744    it++;
[6139]745  }
[7954]746}
747
748/**
749 * writes data to DATA/dicts/newdict
750 * @param data pointer to data
751 * @param length length
752 */
[8623]753void NetworkStream::writeToNewDict( byte * data, int length, bool upstream )
[7954]754{
755  if ( remainingBytesToWriteToDict <= 0 )
756    return;
757 
758  if ( length > remainingBytesToWriteToDict )
759    length = remainingBytesToWriteToDict;
760 
761  std::string fileName = ResourceManager::getInstance()->getDataDir();
762  fileName += "/dicts/newdict";
763 
[8623]764  if ( upstream )
765    fileName += "_upstream";
766  else
767    fileName += "_downstream";
768 
[7954]769  FILE * f = fopen( fileName.c_str(), "a" );
770 
771  if ( !f )
[6139]772  {
[7954]773    PRINTF(2)("could not open %s\n", fileName.c_str());
774    remainingBytesToWriteToDict = 0;
[6139]775    return;
776  }
[7954]777 
778  if ( fwrite( data, 1, length, f ) != length )
[6341]779  {
[7954]780    PRINTF(2)("could not write to file\n");
781    fclose( f );
[6341]782    return;
783  }
[7954]784 
785  fclose( f );
786 
787  remainingBytesToWriteToDict -= length; 
[6139]788}
789
790
[6695]791
792
793
794
Note: See TracBrowser for help on using the repository browser.