Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/tags/0.3.5_alpha/src/lib/network/network_stream.cc @ 10770

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

merged the presentation back

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