Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8684 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
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
114  for ( PeerList::iterator i = peers.begin(); i!=peers.end(); i++)
115  {
116    if ( i->second.socket )
117    {
118      i->second.socket->disconnectServer();
119      delete i->second.socket;
120      i->second.socket = NULL;
121    }
122   
123    if ( i->second.handshake )
124    {
125      delete i->second.handshake;
126      i->second.handshake = NULL;
127    }
128   
129    if ( i->second.connectionMonitor )
130    {
131      delete i->second.connectionMonitor;
132      i->second.connectionMonitor = NULL;
133    }
134  }
135 
136  for ( SynchronizeableList::const_iterator it = getSyncBegin(); it != getSyncEnd(); it ++ )
137    (*it)->setNetworkStream( NULL );
138}
139
140
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
146  this->networkGameManager->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
147  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
148}
149
150
151void NetworkStream::startHandshake()
152{
153  Handshake* hs = new Handshake(false);
154  hs->setUniqueID( 0 );
155  assert( peers[0].handshake == NULL );
156  peers[0].handshake = hs;
157//   peers[0].handshake->setSynchronized( true );
158  //this->connectSynchronizeable(*hs);
159  //this->connectSynchronizeable(*hs);
160  PRINTF(0)("NetworkStream: Handshake created: %s\n", hs->getName());
161}
162
163
164void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
165{
166  this->synchronizeables.push_back(&sync);
167  sync.setNetworkStream( this );
168
169  this->bActive = true;
170}
171
172
173void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync)
174{
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);
179 
180  oldSynchronizeables[sync.getUniqueID()] = SDL_GetTicks();
181}
182
183
184void NetworkStream::processData()
185{
186  int tick = SDL_GetTicks();
187 
188  currentState++;
189 
190  if ( this->type == NET_SERVER )
191  {
192    if ( serverSocket )
193      serverSocket->update();
194   
195    this->updateConnectionList();
196  }
197  else
198  {
199    if ( peers[0].socket && ( !peers[0].socket->isOk() || peers[0].connectionMonitor->hasTimedOut() ) )
200    {
201      PRINTF(1)("lost connection to server\n");
202
203      peers[0].socket->disconnectServer();
204      delete peers[0].socket;
205      peers[0].socket = NULL;
206
207      if ( peers[0].handshake )
208        delete peers[0].handshake;
209      peers[0].handshake = NULL;
210     
211      if ( peers[0].connectionMonitor )
212        delete peers[0].connectionMonitor;
213      peers[0].connectionMonitor = NULL;
214    }
215  }
216
217  cleanUpOldSyncList();
218  handleHandshakes();
219 
220  // order of up/downstream is important!!!!
221  // don't change it
222  handleDownstream( tick );
223  handleUpstream( tick );
224
225}
226
227void NetworkStream::updateConnectionList( )
228{
229  //check for new connections
230
231  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
232
233  if ( tempNetworkSocket )
234  {
235    int clientId;
236    if ( freeSocketSlots.size() >0 )
237    {
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    }
263
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
270
271    PRINTF(0)("New Client: %d\n", clientId);
272
273    //this->connectSynchronizeable(*handshakes[clientId]);
274  }
275
276  //check if connections are ok else remove them
277  for ( PeerList::iterator it = peers.begin(); it != peers.end(); )
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     
292      //assert(false);
293
294      it->second.socket->disconnectServer();
295      delete it->second.socket;
296      it->second.socket = NULL;
297
298      if ( it->second.connectionMonitor )
299        delete it->second.connectionMonitor;
300      it->second.connectionMonitor = NULL;
301     
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 );
309      }
310
311      NetworkGameManager::getInstance()->signalLeftPlayer(it->second.userId);
312
313      freeSocketSlots.push_back( it->second.userId );
314     
315      PeerList::iterator delit = it;
316      it++;
317     
318      peers.erase( delit );
319     
320      continue;
321    }
322   
323    it++;
324  }
325
326
327}
328
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);
335
336  PRINT(0)(" Got %i connected Synchronizeables, showing active Syncs:\n", this->synchronizeables.size());
337  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
338  {
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 );
344
345}
346
347
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;
354
355  //return synchronizeables.size();
356  return n;
357}
358
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() )
371        {
372          if ( !it->second.handshake->allowDel() )
373          {
374            if ( type != NET_SERVER )
375            {
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() );
382            }
383             
384
385            PRINT(0)("handshake finished id=%d\n", it->second.handshake->getNetworkGameManagerId());
386
387            it->second.handshake->del();
388          }
389          else
390          {
391            if ( it->second.handshake->canDel() )
392            {
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;
401            }
402          }
403
404        }
405        else
406        {
407          PRINT(1)("handshake failed!\n");
408          it->second.socket->disconnectServer();
409        }
410      }
411    }
412  }
413}
414
415/**
416 * handle upstream network traffic
417 */
418void NetworkStream::handleUpstream( int tick )
419{
420  int offset;
421  int n;
422 
423  for ( PeerList::reverse_iterator peer = peers.rbegin(); peer != peers.rend(); peer++ )
424  {
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++ )
443    {
444      int oldOffset = offset;
445      Synchronizeable & sync = **it;
446     
447      if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
448        continue;
449
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;
460
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;
473
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      } 
488
489      if ( allZero ) 
490      { 
491        //NETPRINTF(n)("REMOVE ZERO DIFF: %s (%d)\n", sync.getClassName(), sync.getUniqueID());
492        offset = oldOffset; 
493      } 
494
495     
496    }
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   
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 );
515   
516    if ( compLength <= 0 )
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 )
525      writeToNewDict( buf, offset, true );
526   
527    peer->second.connectionMonitor->processUnzippedOutgoingPacket( tick, buf, offset, currentState );
528    peer->second.connectionMonitor->processZippedOutgoingPacket( tick, compBuf, compLength, currentState );
529   
530    //NETPRINTF(n)("send packet: %d userId = %d\n", offset, peer->second.userId);
531  }
532}
533
534/**
535 * handle downstream network traffic
536 */
537void NetworkStream::handleDownstream( int tick )
538{
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++ )
551  {
552   
553    if ( !peer->second.socket )
554      continue;
555
556    while ( 0 < (compLength = peer->second.socket->readPacket( compBuf, UDP_PACKET_SIZE )) )
557    {
558      peer->second.connectionMonitor->processZippedIncomingPacket( tick, compBuf, compLength );
559     
560      //PRINTF(0)("GGGGGOOOOOOOOOOTTTTTTTT: %d\n", compLength);
561      packetLength = Zip::getInstance()->unZip( compBuf, compLength, buf, UDP_PACKET_SIZE );
562
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 )
571        writeToNewDict( buf, packetLength, false );
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;
579     
580      peer->second.connectionMonitor->processUnzippedIncomingPacket( tick, buf, packetLength, state, ackedState );
581
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          }
640
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 );
656
657          if ( !b )
658          {
659            PRINTF(1)("Could not fabricate Object with classID %x\n", leafClassId);
660            offset += syncDataLength;
661            continue;
662          }
663
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        }
680       
681
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);
685
686      }
687     
688      if ( offset != length )
689      {
690        PRINTF(0)("offset (%d) != length (%d)\n", offset, length);
691        peer->second.socket->disconnectServer();
692      }
693     
694     
695      for ( SynchronizeableList::iterator it = synchronizeables.begin(); it != synchronizeables.end(); it++ )
696      {
697        Synchronizeable & sync = **it;
698     
699        if ( !sync.beSynchronized() || sync.getUniqueID() < 0 )
700          continue;
701     
702        sync.handleRecvState( peer->second.userId, state, fromState );
703      }
704     
705      assert( peer->second.lastAckedState <= ackedState );
706      peer->second.lastAckedState = ackedState;
707     
708      assert( peer->second.lastRecvedState < state );
709      peer->second.lastRecvedState = state;
710
711    }
712 
713  }
714 
715}
716
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 );
726}
727
728/**
729 * removes old items from oldSynchronizeables
730 */
731void NetworkStream::cleanUpOldSyncList( )
732{
733  int now = SDL_GetTicks();
734 
735  for ( std::map<int,int>::iterator it = oldSynchronizeables.begin(); it != oldSynchronizeables.end();  )
736  {
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++;
745  }
746}
747
748/**
749 * writes data to DATA/dicts/newdict
750 * @param data pointer to data
751 * @param length length
752 */
753void NetworkStream::writeToNewDict( byte * data, int length, bool upstream )
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 
764  if ( upstream )
765    fileName += "_upstream";
766  else
767    fileName += "_downstream";
768 
769  FILE * f = fopen( fileName.c_str(), "a" );
770 
771  if ( !f )
772  {
773    PRINTF(2)("could not open %s\n", fileName.c_str());
774    remainingBytesToWriteToDict = 0;
775    return;
776  }
777 
778  if ( fwrite( data, 1, length, f ) != length )
779  {
780    PRINTF(2)("could not write to file\n");
781    fclose( f );
782    return;
783  }
784 
785  fclose( f );
786 
787  remainingBytesToWriteToDict -= length; 
788}
789
790
791
792
793
794
Note: See TracBrowser for help on using the repository browser.