Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/multi_player_map/src/lib/network/network_stream.cc @ 9041

Last change on this file since 9041 was 9041, checked in by rennerc, 18 years ago

bug—

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