Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

merged the network branche with the trunk

File size: 22.2 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: claudio
13   co-programmer:
14*/
15
16
17/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
18   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
19*/
20#define DEBUG_MODULE_NETWORK
21
22
23#include "base_object.h"
24#include "network_protocol.h"
25#include "udp_socket.h"
26#include "udp_server_socket.h"
27#include "connection_monitor.h"
28#include "synchronizeable.h"
29#include "network_game_manager.h"
30#include "shared_network_data.h"
31#include "message_manager.h"
32#include "preferences.h"
33#include "zip.h"
34
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
42#include "debug.h"
43#include "class_list.h"
44#include <algorithm>
45
46/* include your own header */
47#include "network_stream.h"
48
49/* probably unnecessary */
50using namespace std;
51
52
53#define PACKAGE_SIZE  256
54
55
56NetworkStream::NetworkStream()
57    : DataStream()
58{
59  this->init();
60  /* initialize the references */
61  this->type = NET_CLIENT;
62}
63
64
65NetworkStream::NetworkStream( std::string host, int port )
66{
67  this->type = NET_CLIENT;
68  this->init();
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 );
73}
74
75
76NetworkStream::NetworkStream( int port )
77{
78  this->type = NET_SERVER;
79  this->init();
80  this->serverSocket = new UdpServerSocket(port);
81  this->bActive = true;
82}
83
84
85void NetworkStream::init()
86{
87  /* set the class id for the base object */
88  this->setClassID(CL_NETWORK_STREAM, "NetworkStream");
89  this->bActive = false;
90  this->serverSocket = NULL;
91  this->networkGameManager = NULL;
92  myHostId = 0;
93  currentState = 0;
94 
95  remainingBytesToWriteToDict = Preferences::getInstance()->getInt( "compression", "writedict", 0 );
96 
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 );
102}
103
104
105NetworkStream::~NetworkStream()
106{
107  if ( this->serverSocket )
108  {
109    serverSocket->close();
110    delete serverSocket;
111    serverSocket = NULL;
112  }
113  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
114  {
115    if ( i->second.socket )
116    {
117      i->second.socket->disconnectServer();
118      delete i->second.socket;
119      i->second.socket = NULL;
120    }
121   
122    if ( i->second.handshake )
123    {
124      delete i->second.handshake;
125      i->second.handshake = NULL;
126    }
127   
128    if ( i->second.connectionMonitor )
129    {
130      delete i->second.connectionMonitor;
131      i->second.connectionMonitor = NULL;
132    }
133  }
134  for ( SynchronizeableList::const_iterator it = getSyncBegin(); it != getSyncEnd(); it ++ )
135    (*it)->setNetworkStream( NULL );
136}
137
138
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
144  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
145  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
146}
147
148
149void NetworkStream::startHandshake()
150{
151  Handshake* hs = new Handshake(false);
152  hs->setUniqueID( 0 );
153  assert( peers[0].handshake == NULL );
154  peers[0].handshake = hs;
155//   peers[0].handshake->setSynchronized( true );
156  //this->connectSynchronizeable(*hs);
157  //this->connectSynchronizeable(*hs);
158  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getName());
159}
160
161
162void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
163{
164  this->synchronizeables.push_back(&sync);
165  sync.setNetworkStream( this );
166
167  this->bActive = true;
168}
169
170
171void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync)
172{
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);
177 
178  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
179}
180
181
182void NetworkStream::processData()
183{
184  int tick = SDL_GetTicks();
185 
186  currentState++;
187 
188  if ( this->type == NET_SERVER )
189  {
190    if ( serverSocket )
191      serverSocket->update();
192   
193    this->updateConnectionList();
194  }
195  else
196  {
197    if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) )
198    {
199      PRINTF(1)("lost connection to server\n");
200
201      peers[0].socket->disconnectServer();
202      delete peers[0].socket;
203      peers[0].socket = NULL;
204
205      if ( peers[0].handshake )
206        delete peers[0].handshake;
207      peers[0].handshake = NULL;
208     
209      if ( peers[0].connectionMonitor )
210        delete peers[0].connectionMonitor;
211      peers[0].connectionMonitor = NULL;
212    }
213  }
214
215  cleanUpOldSyncList();
216  handleHandshakes();
217 
218  // order of up/downstream is important!!!!
219  // don't change it
220  handleDownstream( tick );
221  handleUpstream( tick );
222
223}
224
225void NetworkStream::updateConnectionList( )
226{
227  //check for new connections
228
229  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
230
231  if ( tempNetworkSocket )
232  {
233    int clientId;
234    if ( freeSocketSlots.size() >0 )
235    {
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    }
261
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
268
269    PRINTF(0)("New Client: %d\n", clientId);
270
271    //this->connectSynchronizeable(*handshakes[clientId]);
272  }
273
274  //check if connections are ok else remove them
275  for ( PeerList::iterator it = peers.begin(); it != peers.end(); )
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     
290      //assert(false);
291
292      it->second.socket->disconnectServer();
293      delete it->second.socket;
294      it->second.socket = NULL;
295
296      if ( it->second.connectionMonitor )
297        delete it->second.connectionMonitor;
298      it->second.connectionMonitor = NULL;
299     
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 );
307      }
308
309      NetworkGameManager::getInstance()->signalLeftPlayer(it->second.userId);
310
311      freeSocketSlots.push_back( it->second.userId );
312     
313      PeerList::iterator delit = it;
314      it++;
315     
316      peers.erase( delit );
317     
318      continue;
319    }
320   
321    it++;
322  }
323
324
325}
326
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);
333
334  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
335  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
336  {
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 );
342
343}
344
345
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;
352
353  //return synchronizeables.size();
354  return n;
355}
356
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() )
369        {
370          if ( !it->second.handshake->allowDel() )
371          {
372            if ( type != NET_SERVER )
373            {
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() );
380            }
381             
382
383            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
384
385            it->second.handshake->del();
386          }
387          else
388          {
389            if ( it->second.handshake->canDel() )
390            {
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;
399            }
400          }
401
402        }
403        else
404        {
405          PRINT(1)("handshake failed!\n");
406          it->second.socket->disconnectServer();
407        }
408      }
409    }
410  }
411}
412
413/**
414 * handle upstream network traffic
415 */
416void NetworkStream::handleUpstream( int tick )
417{
418  int offset;
419  int n;
420 
421  for ( PeerList::reverse_iterator peer = peers.rbegin(); peer != peers.rend(); peer++ )
422  {
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++ )
441    {
442      int oldOffset = offset;
443      Synchronizeable & sync = **it;
444     
445      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
446        continue;
447
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;
458
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;
471
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      } 
486
487      if ( allZero ) 
488      { 
489        //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID());
490        offset = oldOffset; 
491      } 
492
493     
494    }
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   
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 );
513   
514    if ( compLength <= 0 )
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 )
523      writeToNewDict( buf, offset, true );
524   
525    peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState );
526    peer->second.connectionMonitor->processZippedOutgoingPacket( tick, compBuf, compLength, currentState );
527   
528    //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId);
529  }
530}
531
532/**
533 * handle downstream network traffic
534 */
535void NetworkStream::handleDownstream( int tick )
536{
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++ )
549  {
550   
551    if ( !peer->second.socket )
552      continue;
553
554    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
555    {
556      peer->second.connectionMonitor->processZippedIncomingPacket( tick, compBuf, compLength );
557     
558      //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
559      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
560
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 )
569        writeToNewDict( buf, packetLength, false );
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;
577     
578      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState );
579
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          }
638
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 );
654
655          if ( !b )
656          {
657            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
658            offset += syncDataLength;
659            continue;
660          }
661
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        }
678       
679
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);
683
684      }
685     
686      if ( offset != length )
687      {
688        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
689        peer->second.socket->disconnectServer();
690      }
691     
692     
693      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
694      {
695        Synchronizeable & sync = **it;
696     
697        if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
698          continue;
699     
700        sync.handleRecvState( peer->second.userId, state, fromState );
701      }
702     
703      assert( peer->second.lastAckedState <= ackedState );
704      peer->second.lastAckedState = ackedState;
705     
706      assert( peer->second.lastRecvedState < state );
707      peer->second.lastRecvedState = state;
708
709    }
710 
711  }
712 
713}
714
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 );
724}
725
726/**
727 * removes old items from oldSynchronizeables
728 */
729void NetworkStream::cleanUpOldSyncList( )
730{
731  int now = SDL_GetTicks();
732 
733  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
734  {
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++;
743  }
744}
745
746/**
747 * writes data to DATA/dicts/newdict
748 * @param data pointer to data
749 * @param length length
750 */
751void NetworkStream::writeToNewDict( byte * data, int length, bool upstream )
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 
762  if ( upstream )
763    fileName += "_upstream";
764  else
765    fileName += "_downstream";
766 
767  FILE * f = fopen( fileName.c_str(), "a" );
768 
769  if ( !f )
770  {
771    PRINTF(2)("could not open %s\n", fileName.c_str());
772    remainingBytesToWriteToDict = 0;
773    return;
774  }
775 
776  if ( fwrite( data, 1, length, f ) != length )
777  {
778    PRINTF(2)("could not write to file\n");
779    fclose( f );
780    return;
781  }
782 
783  fclose( f );
784 
785  remainingBytesToWriteToDict -= length; 
786}
787
788
789
790
791
792
Note: See TracBrowser for help on using the repository browser.