00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "tMemManager.h"
00029 #include "tInitExit.h"
00030 #include "nSimulatePing.h"
00031 #include "nConfig.h"
00032 #include "nNetwork.h"
00033 #include "nServerInfo.h"
00034 #include "tConsole.h"
00035 #include "tDirectories.h"
00036 #include "nSocket.h"
00037 #include "nConfig.h"
00038 #include "nKrawall.h"
00039 #include "tSysTime.h"
00040 #include "tRecorder.h"
00041 #include "tRandom.h"
00042 #include <stdlib.h>
00043 #include <fstream>
00044 #include "tMath.h"
00045 #include <string.h>
00046
00047 #ifndef WIN32
00048 #include <netinet/in.h>
00049 #else
00050 #include <windows.h>
00051 #endif
00052
00053 #include <deque>
00054
00055 #ifdef MACOSX_XCODE
00056 #include "version.h"
00057 #endif // MACOSX_XCODE
00058
00059 #ifdef WIN32
00060 #include "version.h"
00061 #endif // WIN32
00062
00063
00064 static tString sn_myAddress ("*.*.*.*:*");
00065 tString const & sn_GetMyAddress()
00066 {
00067 return sn_myAddress;
00068 }
00069
00071 bool sn_IsLANAddress( tString const & address )
00072 {
00073 if ( address.StartsWith("127.") || address.StartsWith("10.") || address.StartsWith("192.168.") )
00074 {
00075
00076 return true;
00077 }
00078
00079 if( address.StartsWith( "172." ) && address[6] == '.' )
00080 {
00081
00082 int second = address.SubStr(4,2).ToInt();
00083 if ( 16 <= second && second < 32 )
00084 {
00085 return true;
00086 }
00087 }
00088
00089 return false;
00090 }
00091
00092
00093 #ifdef DEBUG
00094 nMessage* sn_WatchMessage = NULL;
00095 unsigned int sn_WatchMessageID = 76;
00096 #endif
00097
00098 #define NO_ACK
00099
00100 tString sn_bigBrotherString;
00101
00102
00103
00104 #ifdef TOP_SOURCE_DIR
00105 #include "nTrueVersion.h"
00106 #endif
00107
00108 #ifndef TRUE_ARMAGETRONAD_VERSION
00109 #define TRUE_ARMAGETRONAD_VERSION VERSION
00110 #endif
00111
00112 tString sn_programVersion (TRUE_ARMAGETRONAD_VERSION) ;
00113
00114 tString sn_serverName("Unnamed Server");
00115
00116 const unsigned int sn_defaultPort = 4534;
00117 unsigned int sn_serverPort = 4534;
00118
00119 tString net_hostip("ANY");
00120
00121 bool big_brother=true;
00122 static tConfItem<bool> sn_bb("BIG_BROTHER",big_brother);
00123
00124 static tConfItemLine sn_sn("SERVER_NAME", sn_serverName);
00125
00126 static tConfItem<int> sn_sport("SERVER_PORT",reinterpret_cast<int&>(sn_serverPort));
00127
00128 static tConfItemLine sn_sbtip("SERVER_IP", net_hostip);
00129
00130 void sn_DisconnectUserNoWarn(int i, const tOutput& reason, nServerInfoBase * redirectTo = 0 );
00131
00132 int sn_defaultDelay=10000;
00133
00135 void sn_Delay()
00136 {
00137 sn_BasicNetworkSystem.Select( sn_defaultDelay / 1000000.0 );
00138 tAdvanceFrame();
00139 }
00140
00141 int sn_maxRateIn=8;
00142 int sn_maxRateOut=8;
00143
00144 static nConnectError sn_Error = nOK;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 bool deb_net=false;
00155
00156 static REAL maxTimeout=1;
00157 static REAL minTimeout=.01;
00158 static REAL pingTimeout=1;
00159 static REAL pingVarianceTimeout=1;
00160 static REAL zeroTimeout=.01;
00161
00162 static REAL sn_GetTimeout( int user )
00163 {
00164 tASSERT( user >= 0 && user <= MAXCLIENTS+1 );
00165
00166 nPingAverager & averager = sn_Connections[ user ].ping;
00167
00168 REAL timeout = pingTimeout * averager.GetPing() + pingVarianceTimeout * sqrtf( averager.GetSnailAverager().GetAverageVariance() );
00169
00170 if ( timeout < minTimeout )
00171 timeout = minTimeout;
00172 if ( timeout > maxTimeout )
00173 timeout = maxTimeout;
00174
00175 return timeout;
00176 }
00177
00178 #ifndef DEBUG
00179 static REAL killTimeout=30;
00180 #else
00181 static REAL killTimeout=30;
00182 #endif
00183
00184 static const int kickOnDemandTimeout = 10;
00185
00186 static bool send_again_warn=false;
00187
00188 #ifdef DEBUG
00189 static int simulate_loss=0;
00190 #else
00191
00192 #endif
00193
00194 int sn_maxNoAck=100;
00195
00196
00197
00198
00199
00200
00201
00202 static nNetState current_state;
00203
00204
00205
00206
00207
00208 nConnectionInfo sn_Connections[MAXCLIENTS+2];
00209
00210 static nAddress peers[MAXCLIENTS+2];
00211 static int timeouts[MAXCLIENTS+2];
00212
00213 #define ACKBACK 1000
00214 static unsigned short lastacks[MAXCLIENTS+2][ACKBACK];
00215 static unsigned short lastackPos[MAXCLIENTS+2];
00216 static unsigned short highest_ack[MAXCLIENTS+2];
00217
00218
00219
00220
00221
00222
00223 static int sn_MaxBackwardsCompatibility = 1000;
00224 static tSettingItem<int> sn_mxc("BACKWARD_COMPATIBILITY",sn_MaxBackwardsCompatibility);
00225
00226 static int sn_newFeatureDelay = 0;
00227 static tSettingItem<int> sn_nfd("NEW_FEATURE_DELAY",sn_newFeatureDelay);
00228
00229
00230 int sn_GetCurrentProtocolVersion();
00231
00232 static const int sn_currentProtocolVersion = sn_GetCurrentProtocolVersion();
00233 static const int sn_backwardCompatibleProtocolVersion = 0;
00234 static const nVersion sn_myVersion( sn_backwardCompatibleProtocolVersion, sn_currentProtocolVersion);
00235 static nVersion sn_currentVersion( sn_myVersion );
00236
00237 const nVersion& sn_MyVersion()
00238 {
00239 return sn_myVersion;
00240 }
00241
00242 const nVersion& sn_CurrentVersion()
00243 {
00244 return sn_currentVersion;
00245 }
00246
00247 nVersion::nVersion()
00248 {
00249 min_=0;
00250 max_=0;
00251 }
00252
00253 nVersion::nVersion( int min, int max )
00254 {
00255 tASSERT( min <= max );
00256 min_=min;
00257 max_=max;
00258 }
00259
00260 bool nVersion::Supported( int version ) const
00261 {
00262 tASSERT( min_ <= max_ );
00263 return version >= min_ && version <= max_;
00264 }
00265
00266 bool nVersion::Merge( const nVersion& a,
00267 const nVersion& b)
00268 {
00269 int min = a.min_;
00270 if ( min < b.min_ )
00271 {
00272 min = b.min_;
00273 }
00274
00275 int max = a.max_;
00276 if ( max > b.max_ )
00277 {
00278 max = b.max_;
00279 }
00280
00281 if ( min <= max )
00282 {
00283 min_ = min;
00284 max_ = max;
00285 return true;
00286 }
00287 else
00288 {
00289 return false;
00290 }
00291 }
00292
00293 bool nVersion::operator == ( const nVersion& other )
00294 {
00295 return this->max_ == other.max_ && this->min_ == other.min_;
00296 }
00297
00298 nVersion& nVersion::operator = ( const nVersion& other )
00299 {
00300 this->min_ = other.min_;
00301 this->max_ = other.max_;
00302
00303 return *this;
00304 }
00305
00306 nMessage& operator >> ( nMessage& m, nVersion& ver )
00307 {
00308 int min,max;
00309 m >> min;
00310 m >> max;
00311
00312 ver = nVersion( min, max );
00313
00314 return m;
00315 }
00316
00317 nMessage& operator << ( nMessage& m, const nVersion& ver )
00318 {
00319 m << ver.Min();
00320 m << ver.Max();
00321
00322 return m;
00323 }
00324
00325 std::istream& operator >> ( std::istream& s, nVersion& ver )
00326 {
00327 int min,max;
00328 s >> min;
00329 s >> max;
00330
00331 ver = nVersion( min, max );
00332
00333 return s;
00334 }
00335
00336 std::ostream& operator << ( std::ostream& s, const nVersion& ver )
00337 {
00338 s << ver.Min() << " ";
00339 s << ver.Max();
00340
00341 return s;
00342 }
00343
00344 nVersionFeature::nVersionFeature( int min, int max )
00345 {
00346 tASSERT( min_ >= sn_MyVersion().Min() );
00347 tASSERT( max < 0 || max <= sn_MyVersion().Max() );
00348
00349 min_ = min;
00350 max_ = max;
00351 }
00352
00353 bool nVersionFeature::Supported()
00354 {
00355 return ( min_ < 0 || sn_CurrentVersion().Max() >= min_ ) && ( max_ < 0 || sn_CurrentVersion().Min() <= max_ );
00356 }
00357
00358 bool nVersionFeature::Supported( int client )
00359 {
00360 if ( client < 0 || client > MAXCLIENTS )
00361 return false;
00362
00363
00364 const nVersion * version = &sn_CurrentVersion();
00365
00366 if ( sn_GetNetState() == nCLIENT )
00367 {
00368
00369 if ( sn_Connections[0].version.Max() > 0 )
00370 version = &sn_Connections[0].version;
00371 }
00372 else
00373 {
00374
00375 version = &sn_Connections[ client ].version;
00376 }
00377
00378
00379 return ( min_ < 0 || version->Max() >= min_ ) && ( max_ < 0 || version->Min() <= max_ );
00380 }
00381
00382 void handle_version_control( nMessage& m )
00383 {
00384 if ( sn_GetNetState() == nCLIENT )
00385 {
00386 m >> sn_currentVersion;
00387
00388
00389 nConfItemVersionWatcher::OnVersionChange( sn_currentVersion );
00390 }
00391 }
00392
00393 nDescriptor versionControl(10, handle_version_control,"version" );
00394
00395 void sn_UpdateCurrentVersion()
00396 {
00397
00398
00399
00400 int min = sn_myVersion.Max() - sn_MaxBackwardsCompatibility;
00401 if ( min < sn_myVersion.Min() )
00402 min = sn_myVersion.Min();
00403
00404
00405 int max = sn_myVersion.Max() - sn_newFeatureDelay;
00406 if ( max < min )
00407 max = min;
00408
00409 nVersion version( min, max );
00410
00411
00412 nConfItemVersionWatcher::AdaptVersion( version );
00413
00414 nVersion maxVersion = version;
00415
00416 if ( sn_GetNetState() == nCLIENT )
00417 {
00418 sn_currentVersion = version;
00419 return;
00420 }
00421
00422 for ( int i = MAXCLIENTS; i>0; --i )
00423 {
00424 const nConnectionInfo& info = sn_Connections[i];
00425 if ( info.socket )
00426 {
00427 if ( ! version.Merge( version, info.version ) )
00428 {
00429
00430 static bool recurse = true;
00431 if ( recurse )
00432 {
00433 recurse = false;
00434 sn_DisconnectUser( i, "$network_kill_incompatible" );
00435 recurse = true;
00436 }
00437
00438 version = maxVersion;
00439 }
00440 }
00441 }
00442
00443
00444 nConfItemVersionWatcher::OnVersionChange( version );
00445
00446 if ( version != sn_currentVersion )
00447 {
00448 sn_currentVersion = version;
00449
00450 nMessage* m = tNEW( nMessage )( versionControl );
00451 (*m) << version;
00452
00453 m->BroadCast();
00454 }
00455 }
00456
00457
00458
00459 nConnectError sn_GetLastError()
00460 {
00461 nConnectError ret = sn_Error;
00462 sn_Error = nOK;
00463 return ret;
00464 }
00465
00466
00467
00468
00469
00470 static void reset_last_acks(int i){
00471 for(int j=ACKBACK-1;j>=0;j--)
00472 lastacks[i][j]=0;
00473 lastackPos[i]=0;
00474 highest_ack[i]=0;
00475 }
00476
00477
00478
00479 int sn_maxClients=MAXCLIENTS;
00480
00481 static tSettingItem< int > sn_maxClientsConf( "MAX_CLIENTS", sn_maxClients );
00482
00483 int sn_allowSameIPCountSoft=4;
00484 static tSettingItem< int > sn_allowSameIPCountSoftConf( "MAX_CLIENTS_SAME_IP_SOFT", sn_allowSameIPCountSoft );
00485
00486 int sn_allowSameIPCountHard=8;
00487 static tSettingItem< int > sn_allowSameIPCountHardConf( "MAX_CLIENTS_SAME_IP_HARD", sn_allowSameIPCountHard );
00488
00489
00490
00491
00492
00493 int sn_myNetID=0;
00494
00495
00496 #define IDS_RESERVED 16 // number of message IDs reserved for special purposes: id 0 is reserved for no-ack messages.
00497 unsigned short current_id=1;
00498
00499
00500
00501 class planned_send:public tHeapElement{
00502 protected:
00503 int peer;
00504 public:
00505 planned_send(REAL priority,int peer);
00506 ~planned_send();
00507
00508 virtual tHeapBase *Heap() const;
00509
00510
00511 void add_to_priority(REAL diff);
00512
00513
00514 virtual void execute()=0;
00515 };
00516
00517 class nMessage_planned_send:public planned_send{
00518 tCONTROLLED_PTR(nMessage) m;
00519 bool ack;
00520
00521 public:
00522 nMessage_planned_send(nMessage *m,REAL priority,bool ack,int peer);
00523 ~nMessage_planned_send();
00524
00525 virtual void execute();
00526 };
00527
00528
00529
00530 unsigned short nDescriptor::s_nextID(1);
00531
00532 #define MAXDESCRIPTORS 400
00533 static nDescriptor* descriptors[MAXDESCRIPTORS];
00534
00535 static nDescriptor* nDescriptor_anchor;
00536
00537 nDescriptor::nDescriptor(unsigned short identification,
00538 nHandler *handle,const char *Name, bool awl)
00539 :tListItem<nDescriptor>(nDescriptor_anchor),
00540 id(identification),handler(handle),name(Name), acceptWithoutLogin(awl)
00541 {
00542 #ifdef DEBUG
00543 #ifndef WIN32
00544
00545 #endif
00546 #endif
00547 if (MAXDESCRIPTORS<=id || descriptors[id]!=NULL){
00548 con << "Descriptor " << id << " already used!\n";
00549 exit(-1);
00550 }
00551 s_nextID=id+1;
00552 descriptors[id]=this;
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 int nCurrentSenderID::currentSenderID_ = 0;
00572
00573 void nDescriptor::HandleMessage(nMessage &message){
00574 static tArray<bool> warned;
00575
00576
00577 nCurrentSenderID currentSender( message.SenderID() );
00578
00579 #ifdef DEBUG_X
00580 if (message.descriptor>1)
00581 con << "RMT " << message.descriptor << "\n";
00582 #endif
00583
00584 #ifndef NOEXCEPT
00585 try{
00586 #endif
00587 nDescriptor *nd = 0;
00588
00589
00590 if ( message.descriptor < MAXDESCRIPTORS )
00591 nd=descriptors[message.descriptor];
00592
00593 if (nd){
00594 if ((message.SenderID() <= MAXCLIENTS) || nd->acceptWithoutLogin)
00595 nd->handler(message);
00596 }
00597 else
00598 if (!warned[message.Descriptor()]){
00599 tOutput warn;
00600 warn.SetTemplateParameter(1, message.Descriptor());
00601 warn << "$network_warn_unknowndescriptor";
00602 con << warn;
00603 warned[message.Descriptor()]=true;
00604 }
00605 #ifndef NOEXCEPT
00606 }
00607 catch(nIgnore const &){
00608
00609 }
00610 catch(nKillHim const &){
00611
00612 con << tOutput("$network_error");
00613 sn_DisconnectUser(message.SenderID(), "$network_kill_error" );
00614 }
00615 catch( tGenericException & e )
00616 {
00617
00618
00619 sn_ConsoleOut( e.GetName() + ": " + e.GetDescription() + '\n', message.SenderID() );
00620 }
00621
00622 #endif
00623 }
00624
00625
00626
00627
00628 void ack_handler(nMessage &m){
00629 while (!m.End()){
00630 sn_Connections[m.SenderID()].AckReceived();
00631
00632 unsigned short ack;
00633 m.Read(ack);
00634
00635 nWaitForAck::Ackt(ack,m.SenderID());
00636 }
00637 }
00638
00639 static nDescriptor s_Acknowledge(1,ack_handler,"ack");
00640
00641
00642 class nWaitForAck;
00643 static tList<nWaitForAck> sn_pendingAcks;
00644
00645
00646 static nTimeRolling netTime;
00647
00648 #ifdef NET_DEBUG
00649 static int acks=0;
00650 static int max_acks=0;
00651 #endif
00652
00653 nWaitForAck::nWaitForAck(nMessage* m,int rec)
00654 :id(-1),message(m),receiver(rec)
00655 {
00656 #ifdef DEBUG
00657
00658 if ( rec == 0 && sn_GetNetState() == nSERVER )
00659 st_Breakpoint();
00660 #endif
00661
00662 if (!message)
00663 tERR_ERROR("Null ack!");
00664
00665 if (message->Descriptor()!=s_Acknowledge.ID())
00666 sn_Connections[receiver].ackPending++;
00667 else
00668 tERR_ERROR("Should not wait for ack of an ack message itself.");
00669
00670
00671 #ifdef NET_DEBUG
00672 acks++;
00673 #endif
00674
00675 timeFirstSent=::netTime;
00676 timeLastSent=::netTime;
00677
00678 timeouts=0;
00679
00680 timeout=sn_GetTimeout( rec );
00681
00682 #ifdef nSIMULATE_PING
00683 timeSendAgain=::netTime + nSIMULATE_PING;
00684 #ifndef WIN32
00685 tRandomizer & randomizer = tReproducibleRandomizer::GetInstance();
00686 timeSendAgain+= randimizer.Get() * nSIMULATE_PING_VARIANT;
00687
00688 #endif
00689 #else
00690 const REAL packetLossScale = .003;
00691 const REAL maxTimeoutFactor = 1.2;
00692
00693
00694 REAL timeoutFactor = 1 + (maxTimeoutFactor-1)*packetLossScale/(sn_Connections[receiver].PacketLoss() + packetLossScale);
00695 timeSendAgain=::netTime + timeout*timeoutFactor + zeroTimeout;
00696 #endif
00697 sn_pendingAcks.Add(this,id);
00698 }
00699
00700 nWaitForAck::~nWaitForAck(){
00701 #ifdef NET_DEBUG
00702 acks--;
00703 if (acks>max_acks){
00704 max_acks=acks;
00705
00706 }
00707 #endif
00708
00709 if (bool(message) && message->Descriptor()!=s_Acknowledge.ID())
00710 {
00711 sn_Connections[receiver].ackPending--;
00712 sn_Connections[receiver].ReliableMessageSent();
00713 }
00714 else
00715 {
00716 tERR_ERROR( "No message." );
00717 }
00718
00719
00720 sn_pendingAcks.Remove(this,id);
00721 tCHECK_DEST;
00722 }
00723
00724 void nWaitForAck::Ackt(unsigned short id,unsigned short peer){
00725 int success=0;
00726 for(int i=sn_pendingAcks.Len()-1;i>=0;i--){
00727 nWaitForAck * ack = sn_pendingAcks(i);
00728 if (ack->message->MessageID()==id &&
00729 ack->receiver==peer){
00730 success=1;
00731
00732 #ifdef DEBUG
00733
00734
00735 #endif
00736
00737 #ifdef DEBUG_X
00738 if (ack->message->descriptor>1)
00739 con << "AT " << ack->message->descriptor << '\n';
00740 #endif
00741
00742
00743 REAL thisping=netTime - ack->timeFirstSent;
00744 sn_Connections[peer].ping.Add( thisping, 1/(1 + 10 * REAL(ack->timeouts * ack->timeouts * ack->timeouts ) ) );
00745
00746 ack->AckExtraAction();
00747 delete ack;
00748 ::timeouts[peer]=0;
00749 if (i<sn_pendingAcks.Len()-1) i++;
00750 }
00751 }
00752
00753 #ifdef DEBUG_X
00754 if (!success && peer!=MAXCLIENTS+1)
00755 {
00756 con << "Ack " << id << ':' << peer << " was not asked for.\n";
00757 if (sn_pendingAcks.Len()) con << "Expected:\n";
00758 for(int i=sn_pendingAcks.Len()-1;i>=0;i--){
00759 con << i << "\t:"
00760 << sn_pendingAcks[i]->message->messageIDBig_ << ":"
00761 << sn_pendingAcks[i]->receiver << '\n';
00762 }
00763 }
00764 #endif
00765 }
00766
00767 void nWaitForAck::AckAllPeer(unsigned short peer){
00768 for(int i=sn_pendingAcks.Len()-1;i>=0;i--){
00769 if (sn_pendingAcks(i)->receiver==peer){
00770 delete sn_pendingAcks(i);
00771 if (i<sn_pendingAcks.Len()-1) i++;
00772 }
00773 }
00774 }
00775
00776 void nWaitForAck::Resend(){
00777 static tReproducibleRandomizer randomizer;
00778
00779 for(int i=sn_pendingAcks.Len()-1;i>=0;i--){
00780 nWaitForAck* pendingAck = sn_pendingAcks(i);
00781
00782 nConnectionInfo & connection = sn_Connections[pendingAck->receiver];
00783
00784
00785 if ( !connection.bandwidthControl_.CanSend() )
00786 continue;
00787
00788 REAL packetLoss = connection.PacketLoss();
00789 REAL timeout = pendingAck->timeout;
00790
00791
00792 bool resend = (pendingAck->timeSendAgain + timeout * .1 <=netTime);
00793
00794
00795 if ( !resend && connection.sendBuffer_.Len() > 0 )
00796 {
00797
00798 if ( pendingAck->timeSendAgain <= netTime )
00799 resend = true;
00800
00801
00802 else if ( pendingAck->timeouts < 3 && pow( packetLoss, pendingAck->timeouts + 1 ) > .01 &&
00803 connection.bandwidthControl_.Control( nBandwidthControl::Usage_Planning ) >100 )
00804 resend = true;
00805
00806
00807
00808
00809
00810 }
00811
00812 if ( resend ){
00813
00814
00815
00816 ::timeouts[pendingAck->receiver]++;
00817 pendingAck->timeouts++;
00818
00819 if(netTime - pendingAck->timeFirstSent > killTimeout &&
00820 ::timeouts[pendingAck->receiver] > 20){
00821
00822 if (pendingAck->receiver<=MAXCLIENTS){
00823 tOutput o;
00824 o.SetTemplateParameter(1, pendingAck->receiver);
00825 o << "$network_error_timeout";
00826 con << o;
00827 sn_DisconnectUser(pendingAck->receiver, "$network_kill_timeout" );
00828
00829 sn_Error = nTIMEOUT;
00830
00831 if (i>=sn_pendingAcks.Len())
00832 i=sn_pendingAcks.Len()-1;
00833 }
00834 else
00835 delete pendingAck;
00836 }
00837 else{
00838 #ifdef DEBUG
00839
00840
00841 #endif
00842
00843 if (connection.socket){
00844
00845 {
00846 REAL timeoutFactor = .9 + .1 * pendingAck->timeouts + randomizer.Get() * .1;
00847 pendingAck->timeSendAgain=netTime+timeout * timeoutFactor;
00848 pendingAck->timeLastSent=netTime;
00849
00850 if (send_again_warn){
00851 con << "sending packet again: " ;
00852 deb_net=true;
00853 }
00854 connection.ReliableMessageSent();
00855 pendingAck->message->SendImmediately
00856 (pendingAck->receiver,false);
00857 deb_net=false;
00858 }
00859 }
00860 else
00861 delete pendingAck;
00862 }
00863 }
00864 }
00865 }
00866
00867
00868
00869
00870
00871
00872 #ifdef NET_DEBUG
00873 static int nMessages=0;
00874 static int max_nMessages=0;
00875 #endif
00876
00877 #ifdef DEBUG
00878 void BreakOnMessageID( unsigned int messageID )
00879 {
00880 if (messageID == sn_WatchMessageID && messageID != 0 )
00881 {
00882 int x;
00883 x = 0;
00884 }
00885 }
00886 #endif
00887
00888 class nMessageIDExpander
00889 {
00890 unsigned long quarters[4];
00891 public:
00892 nMessageIDExpander()
00893 {
00894 for (int i=3; i>=0; --i)
00895 quarters[i]=i << 14;
00896 }
00897
00898 unsigned long ExpandMessageID( unsigned short id )
00899 {
00900
00901 int thisQuarter = ( id >> 14 ) & 3;
00902
00903
00904 int nextQuarter = ( thisQuarter + 1 ) & 3;
00905
00906
00907 quarters[nextQuarter] = quarters[thisQuarter] + ( 1 << 14 );
00908
00909
00910 return quarters[thisQuarter] | id;
00911 }
00912 };
00913
00915
00916 static unsigned long int sn_ExpandMessageID( unsigned short id, unsigned short sender )
00917 {
00918 #ifdef DEBUG
00919 BreakOnMessageID( id );
00920 #endif
00921
00922 static nMessageIDExpander expanders[MAXCLIENTS+2];
00923
00924 tASSERT( sender <= MAXCLIENTS+2 )
00925 return expanders[sender].ExpandMessageID(id);
00926 }
00927
00928 nMessage::nMessage(unsigned short*& buffer,short sender, int lenLeft )
00929 :descriptor(ntohs(*(buffer++))),messageIDBig_(sn_ExpandMessageID(ntohs(*(buffer++)),sender)),
00930 senderID(sender),readOut(0){
00931 #ifdef NET_DEBUG
00932 nMessages++;
00933 #endif
00934
00935 tRecorderSync< unsigned long >::Archive( "_MESSAGE_ID_IN", 3, messageIDBig_ );
00936 tRecorderSync< unsigned short >::Archive( "_MESSAGE_DECL_IN", 3, descriptor );
00937
00938 unsigned short len=ntohs(*(buffer++));
00939 lenLeft--;
00940 if ( len > lenLeft )
00941 {
00942 len = lenLeft;
00943 #ifndef NOEXCEPT
00944 throw nKillHim();
00945 #endif
00946 }
00947 for(int i=0;i<len;i++)
00948 data[i]=ntohs(*(buffer++));
00949
00950 #ifdef DEBUG
00951 BreakOnMessageID( messageIDBig_ );
00952 #endif
00953 }
00954
00955 nMessage::nMessage(const nDescriptor &d)
00956 :descriptor(d.id),
00957 senderID(::sn_myNetID), readOut(0){
00958 #ifdef NET_DEBUG
00959 nMessages++;
00960 #endif
00961
00962 current_id++;
00963 if (current_id <= IDS_RESERVED)
00964 current_id = IDS_RESERVED + 1;
00965
00966 messageIDBig_ = current_id;
00967
00968 #ifdef DEBUG
00969 BreakOnMessageID( messageIDBig_ );
00970 #endif
00971
00972 tRecorderSync< unsigned long >::Archive( "_MESSAGE_ID_OUT", 3, messageIDBig_ );
00973 tRecorderSync< unsigned short >::Archive( "_MESSAGE_DECL_OUT", 3, descriptor );
00974 }
00975
00976
00977 nMessage::~nMessage(){
00978 #ifdef NET_DEBUG
00979 nMessages--;
00980 if (nMessages>max_nMessages){
00981 max_nMessages=nMessages;
00982 con << "MN=" << max_nMessages <<'\n';
00983 }
00984 #endif
00985
00986 #ifdef DEBUG_X
00987 if (descriptor>1)
00988 con << "DMT " << descriptor << "\n";
00989 #endif
00990
00991 tCHECK_DEST;
00992 }
00993
00994
00995
00996
00997 void nMessage::BroadCast(bool ack){
00998 tControlledPTR< nMessage > keep( this );
00999 if (sn_GetNetState()==nCLIENT)
01000 Send(0,ack);
01001
01002 if (sn_GetNetState()==nSERVER){
01003 for(int i=MAXCLIENTS;i>0;i--){
01004 if (sn_Connections[i].socket)
01005 Send(i,ack);
01006 }
01007 }
01008 }
01009
01010
01011 static nVersionFeature sn_ZeroMessageCrashfix( 1 );
01012
01013 nMessage& nMessage::operator << (const tString &s){
01014 if ( !sn_ZeroMessageCrashfix.Supported() && s.Len() <= 0 )
01015 {
01016 return this->operator<<( s + " " );
01017 }
01018
01019 unsigned short len=s.Size()+1;
01020
01021
01022 while(len > 1 && s(len-2)==0)
01023 {
01024 --len;
01025 }
01026
01027 Write(len);
01028 int i;
01029
01030 char const * sRaw = s;
01031
01032
01033 for(i=0;i+1<len;i+=2)
01034 Write(sRaw[i]+(sRaw[i+1] << 8));
01035
01036
01037 if (i<len)
01038 Write(sRaw[i]);
01039
01040 return *this;
01041 }
01042
01043 nMessage& nMessage::operator << (const tColoredString &s){
01044 return *this << static_cast< const tString & >( s );
01045 }
01046
01047 nMessage& nMessage::operator << ( const tOutput &o ){
01048 return *this << tString( static_cast< const char * >( o ) );
01049 }
01050
01051 bool sn_filterColorStrings = false;
01052 static tConfItem<bool> cs("FILTER_COLOR_STRINGS",sn_filterColorStrings);
01053
01054 static void sn_AddToString( tString & s, tString::CHAR c )
01055 {
01056 if ( c )
01057 s += c;
01058 }
01059
01060 nMessage& nMessage::ReadRaw(tString &s )
01061 {
01062 s.Clear();
01063 unsigned short w,len;
01064 Read(len);
01065 if ( len > 0 )
01066 {
01067 s.reserve(len);
01068 for(int i=0;i<len;i+=2){
01069 Read(w);
01070 tString::CHAR c1 = w & 255;
01071 sn_AddToString( s, c1 );
01072 if (i+1<len)
01073 sn_AddToString( s, (w-c1) >> 8 );
01074 }
01075 }
01076
01077 return *this;
01078 }
01079
01080 nMessage& nMessage::operator >> (tColoredString &s )
01081 {
01082
01083 ReadRaw( s );
01084
01085
01086 if ( sn_GetNetState() == nSERVER )
01087 {
01088 s.NetFilter();
01089 s.RemoveTrailingColor();
01090 }
01091
01092
01093 if ( sn_filterColorStrings )
01094 s = tColoredString::RemoveColors( s );
01095
01096 return *this;
01097 }
01098
01099 nMessage& nMessage::operator >> (tString &s )
01100 {
01101 tColoredString safe;
01102 operator>>( safe );
01103 s = safe;
01104
01105 return *this;
01106 }
01107
01108
01109 #define MANT 26
01110 #define EXP (32-MANT)
01111 #define MS (MANT-1)
01112
01113
01114 typedef struct{
01115 int mant:MANT;
01116 unsigned int exp:EXP;
01117 } myfloat;
01118
01119
01120 nMessage& nMessage::operator<<(const REAL &x){
01121
01122
01123 #ifdef DEBUG
01124
01125
01126
01127 if(sizeof(myfloat)!=sizeof(int))
01128 tERR_ERROR_INT("floating ePoint format does not work!");
01129 #endif
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 REAL y=x;
01146
01147 unsigned int negative=0;
01148 if (y<0){
01149 y=-y;
01150 negative=1;
01151 }
01152
01153 unsigned int exp=0;
01154 while ( fabs(y)>=64 && exp < (1<<EXP)-6 )
01155 {
01156 exp +=6;
01157 y/=64;
01158 }
01159 while ( fabs(y)>=1 && exp < (1<<EXP)-1 )
01160 {
01161 exp++;
01162 y/=2;
01163 }
01164
01165 unsigned int mant=int(y*(1<<MS));
01166
01167
01168
01169 if (mant>((1<<MS))-1)
01170 mant=(1<<MS)-1;
01171
01172 if (exp>(1<<EXP)-1){
01173 exp=(1<<EXP)-1;
01174 if (mant>0)
01175 mant=(1<<MS)-1;
01176 }
01177
01178
01179
01180 unsigned int trans=(mant & ((1<<MS)-1)) | (negative << MS) | (exp << MANT);
01181
01182
01183
01184
01185
01186
01187 operator<<(reinterpret_cast<int &>(trans));
01188
01189 #ifdef DEBUG
01190
01191
01192
01193
01194
01195
01196 unsigned int mant2=trans & ((1 << MS)-1);
01197 unsigned int negative2=(trans >> MS) & 1;
01198 unsigned int nt=trans-mant-(negative << MS);
01199 unsigned int exp2=nt >> MANT;
01200
01201 if (mant2!=mant || negative2!=negative || exp2!=exp)
01202 tERR_ERROR_INT("Floating ePoint tranfer failure!");
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214 REAL z=REAL(mant)/(1<<MS);
01215 if (negative)
01216 z=-z;
01217
01218 while (exp>=6){
01219 exp-=6;
01220 z*=64;
01221 }
01222 while (exp>0){
01223 exp--;
01224 z*=2;
01225 }
01226
01227 if (fabs(z-x)>(fabs(x)+1)*.001)
01228 tERR_ERROR_INT("Floating ePoint tranfer failure!");
01229
01230
01231 #endif
01232
01233 return *this;
01234 }
01235
01236 nMessage& nMessage::operator>>(REAL &x){
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248 unsigned int trans;
01249 operator>>(reinterpret_cast<int &>(trans));
01250
01251 int mant=trans & ((1 << MS)-1);
01252 unsigned int negative=(trans >> MS) & 1;
01253 unsigned int exp=(trans-mant-(negative << MS)) >> MANT;
01254
01255 x=REAL(mant)/(1<<MS);
01256 if (negative)
01257 x=-x;
01258
01259 #ifdef DEBUG
01260
01261 #endif
01262
01263 while (exp>=6){
01264 exp-=6;
01265 x*=64;
01266 }
01267 while (exp>0){
01268 exp--;
01269 x*=2;
01270 }
01271
01272 #ifdef DEBUG
01273 #ifndef WIN32
01274 if (!finite(x))
01275 st_Breakpoint();
01276
01277 #endif
01278 #endif
01279 return *this;
01280 }
01281
01282 nMessage& nMessage::operator<< (const short &x){
01283 Write((reinterpret_cast<const short *>(&x))[0]);
01284
01285 return *this;
01286 }
01287
01288 nMessage& nMessage::operator>> (short &x){
01289 Read(reinterpret_cast<unsigned short *>(&x)[0]);
01290
01291 return *this;
01292 }
01293
01294 nMessage& nMessage::operator<< (const int &x){
01295 unsigned short a=x & (0xFFFF);
01296 short b=(x-a) >> 16;
01297
01298 Write(a);
01299 operator<<(b);
01300
01301 return *this;
01302 }
01303
01304 nMessage& nMessage::operator>> (int &x){
01305 unsigned short a;
01306 short b;
01307
01308 Read(a);
01309 operator>>(b);
01310
01311 x=(b << 16)+a;
01312
01313 return *this;
01314 }
01315
01316 nMessage& nMessage::operator<< (const bool &x){
01317 if (x)
01318 Write(1);
01319 else
01320 Write(0);
01321
01322 return *this;
01323 }
01324
01325 nMessage& nMessage::operator>> (bool &x){
01326 unsigned short y;
01327 Read(y);
01328 x= (y!=0);
01329
01330 return *this;
01331 }
01332
01333
01334 void nMessage::Read(unsigned short &x){
01335 if (End()){
01336 tOutput o;
01337 st_Breakpoint();
01338 o.SetTemplateParameter(1, senderID);
01339 o << "$network_error_shortmessage";
01340 con << o;
01341
01342 nReadError( false );
01343 }
01344 else
01345 x=data(readOut++);
01346 }
01347
01348
01349
01350
01351
01352
01353 static bool login_failed=false;
01354 static bool login_succeeded=false;
01355
01356
01357
01358
01359 static nKrawall::nSalt loginSalt;
01360
01361 static nHandler *real_req_info_handler=NULL;
01362
01363 void req_info_handler(nMessage &m){
01364 if (real_req_info_handler)
01365 (*real_req_info_handler)(m);
01366 if (m.SenderID()==MAXCLIENTS+1)
01367 sn_DisconnectUser(MAXCLIENTS+1, "$network_kill_logout");
01368 }
01369
01370 static nDescriptor req_info(2,req_info_handler,"req_info");
01371
01372 void RequestInfoHandler(nHandler *handle){
01373 real_req_info_handler=handle;
01374 }
01375
01376
01377 static std::auto_ptr< nServerInfoBase > sn_redirectTo;
01378 std::auto_ptr< nServerInfoBase > sn_GetRedirectTo()
01379 {
01380 return sn_redirectTo;
01381 }
01382
01383 nServerInfoBase * sn_PeekRedirectTo()
01384 {
01385 return sn_redirectTo.get();
01386 }
01387
01388 void login_deny_handler(nMessage &m){
01389 if ( !m.End() )
01390 {
01391
01392
01393
01394 m >> sn_DenyReason;
01395 }
01396 else
01397 {
01398 sn_DenyReason = tOutput( "$network_kill_unknown" );
01399 }
01400
01401 if ( !m.End() )
01402 {
01403
01404 tString connectionName;
01405 m >> connectionName;
01406 int port;
01407 m >> port;
01408
01409 if ( connectionName.Len() > 1 )
01410 {
01411
01412 sn_redirectTo = std::auto_ptr< nServerInfoBase>( new nServerInfoRedirect( connectionName, port ) );
01413 }
01414 }
01415
01416 if (!login_failed)
01417 con << tOutput("$network_login_denial");
01418 if (sn_GetNetState()!=nSERVER){
01419 login_failed=true;
01420 login_succeeded=false;
01421 sn_SetNetState(nSTANDALONE);
01422 }
01423 }
01424
01425 static nDescriptor login_deny(3,login_deny_handler,"login_deny");
01426
01427 void login_handler_1( nMessage&m );
01428 void login_handler_2( nMessage&m );
01429 void logout_handler( nMessage&m );
01430
01431 nDescriptor login(6,login_handler_1,"login1", true);
01432 nDescriptor login_2(11,login_handler_2,"login2", true);
01433 nDescriptor logout(7,logout_handler,"logout");
01434
01435 tString sn_DenyReason;
01436
01437 void login_ignore_handler(nMessage &m){
01438 if (sn_GetNetState()!=nSERVER && !login_succeeded){
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453 }
01454
01455
01456 }
01457
01458 static nDescriptor login_ignore(4,login_ignore_handler,"login_ignore");
01459
01460
01461 void first_fill_ids();
01462
01463
01464 extern bool sn_AcceptingFromMaster;
01465
01466 void login_accept_handler(nMessage &m){
01467 if (sn_GetNetState()!=nSERVER && m.SenderID() == 0){
01468 unsigned short id=0;
01469 m.Read(id);
01470
01471
01472 if ( !m.End() )
01473 {
01474 m >> sn_Connections[0].version;
01475
01476 #ifdef DEBUG
01477 #define NOEXPIRE
01478 #endif
01479
01480 #ifndef NOEXPIRE
01481 #ifndef DEDICATED
01482
01483 if ( !sn_AcceptingFromMaster &&
01484 ( strstr( VERSION, "rc" ) || strstr( VERSION, "alpha" ) || strstr( VERSION, "beta" ) ) &&
01485 sn_Connections[0].version.Max() > sn_currentProtocolVersion + 1 )
01486 {
01487 throw tGenericException( tOutput("$testing_version_expired"), tOutput("$testing_version_expired_title" ) );
01488 }
01489 #endif
01490 #endif
01491 }
01492 else
01493 sn_Connections[0].version = nVersion( 0, 0);
01494
01495
01496 if ( !m.End() )
01497 {
01498
01499 tString address;
01500 m >> address;
01501 if ( !sn_IsLANAddress( address ) )
01502 {
01503 sn_myAddress = address;
01504 }
01505
01506
01507 nKrawall::nSalt replySalt;
01508 nKrawall::ReadScrambledPassword( m, replySalt );
01509
01510 int compare = memcmp( &loginSalt,&replySalt, sizeof(replySalt) );
01511
01512
01513 static const char * section = "LOGIN_SALT";
01514 tRecorder::Playback( section, compare );
01515 tRecorder::Record( section, compare );
01516
01517 if ( compare != 0 )
01518 {
01519 nReadError( false );
01520 }
01521 }
01522
01523
01524 login_succeeded=true;
01525 sn_myNetID=id;
01526
01527 first_fill_ids();
01528 }
01529 }
01530
01531 static nDescriptor login_accept(5,login_accept_handler,"login_accept", true);
01532
01533
01534
01535
01536
01537
01538 int CountSameIP( int user, bool reset=false )
01539 {
01540 static int sameIP[ MAXCLIENTS+2 ];
01541 tASSERT( user >= 0 && user <= MAXCLIENTS+1 );
01542
01543 if ( reset )
01544 {
01545 int count = 0;
01546 for(int user2=1;user2<=MAXCLIENTS;++user2)
01547 {
01548 if(!sn_Connections[user2].socket)
01549 continue;
01550
01551 if ( user2 != user && nAddress::Compare( peers[user], peers[user2] ) >=0 )
01552 {
01553 count++;
01554 }
01555 }
01556
01557 sameIP[user] = count;
01558 }
01559
01560 return sameIP[user];
01561 }
01562
01563
01564 int CountSameConnection( int user )
01565 {
01566 int count = 0;
01567 for(int user2=1;user2<=MAXCLIENTS;++user2)
01568 {
01569 if( NULL == sn_Connections[user2].socket )
01570 continue;
01571
01572 if ( user2 != user && nAddress::Compare( peers[user], peers[user2] ) == 0 )
01573 {
01574 count++;
01575 }
01576 }
01577
01578 return count;
01579 }
01580
01581
01582 int GetFreeSlot()
01583 {
01584 int user;
01585
01586
01587 if ( sn_NumUsers() < sn_maxClients )
01588 {
01589 for(user=1;user<=sn_maxClients;++user)
01590 {
01591
01592 if(!sn_Connections[user].socket)
01593 {
01594 return user;
01595 }
01596 }
01597 }
01598
01599 int best = -1;
01600
01601
01602
01603 int bestCount = sn_allowSameIPCountSoft-1;
01604
01605
01606 for(user=1;user<=MAXCLIENTS;++user)
01607 {
01608 int count = CountSameIP( user );
01609 if ( count > bestCount )
01610 {
01611 bestCount = count;
01612 best = user;
01613 }
01614 }
01615 if ( best > 0 )
01616 return best;
01617
01618 return -1;
01619 }
01620
01621 static REAL sn_minBan = 120;
01622 static tSettingItem< REAL > sn_minBanSetting( "NETWORK_MIN_BAN", sn_minBan );
01623
01624
01625 extern bool FloodProtection( nMessage const & m );
01626
01627
01628 static bool sn_lockOut028tTest = true;
01629 static tSettingItem< bool > sn_lockOut028TestConf( "NETWORK_LOCK_OUT_028_TEST", sn_lockOut028tTest );
01630
01631 int login_handler( nMessage &m, unsigned short rate ){
01632 nCurrentSenderID senderID;
01633
01634
01635 nVersion version;
01636 tString supportedAuthenticationMethods("");
01637 nKrawall::nSalt salt;
01638 if ( !m.End() )
01639 {
01640
01641 m >> version;
01642
01643
01644 supportedAuthenticationMethods = "bmd5";
01645 }
01646 if ( !m.End() )
01647 {
01648
01649 m >> supportedAuthenticationMethods;
01650 }
01651 if ( !m.End() )
01652 {
01653
01654 nKrawall::ReadScrambledPassword( m, salt );
01655 }
01656
01657
01658 if (sn_GetNetState() != nSERVER)
01659 return -1;
01660
01661
01662 nMachine & machine = nMachine::GetMachine( m.SenderID() );
01663 REAL banned = machine.IsBanned();
01664 if ( banned > 0 )
01665 {
01666
01667 tString const & reason = machine.GetBanReason();
01668
01669
01670 if ( banned < sn_minBan )
01671 {
01672 machine.Ban( sn_minBan );
01673 banned = sn_minBan;
01674 }
01675 else
01676 con << tOutput( "$network_ban", machine.GetIP() , int(banned/60), reason.Len() > 1 ? reason : tOutput( "$network_ban_noreason" ) );
01677
01678 sn_DisconnectUser(m.SenderID(), tOutput( "$network_kill_banned", int(banned/60), reason ) );
01679 }
01680
01681
01682 if( CountSameConnection( m.SenderID() ) > 0 )
01683 return -1;
01684
01685
01686 if ( FloodProtection( m ) )
01687 return -1;
01688
01689 bool success=false;
01690
01691 int new_id = -1;
01692
01693
01694
01695
01696
01697 nVersion mergedVersion;
01698 if ( !mergedVersion.Merge( version, sn_CurrentVersion() ) )
01699 {
01700 sn_DisconnectUser(m.SenderID(), "$network_kill_incompatible");
01701 }
01702
01703
01704 if ( sn_lockOut028tTest && version.Max() >= 5 && version.Max() <= 10 )
01705 {
01706 sn_DisconnectUser(m.SenderID(), "0.2.8_beta and 0.2.8.0_rc versions have a dangerous security flaw and are obsoleted, please upgrade to 0.2.8.2.1.");
01707 }
01708
01709 if (m.SenderID()!=MAXCLIENTS+1)
01710 {
01711
01712 (new nMessage(login_ignore))->Send(m.SenderID());
01713 }
01714 else if (sn_Connections[m.SenderID()].socket)
01715 {
01716 if ( sn_maxClients > MAXCLIENTS )
01717 sn_maxClients = MAXCLIENTS;
01718
01719
01720 if ( CountSameIP( m.SenderID(), true ) < sn_allowSameIPCountHard )
01721 {
01722
01723 new_id = GetFreeSlot();
01724 if ( new_id > 0 )
01725 {
01726 if(sn_Connections[new_id].socket)
01727 sn_DisconnectUser( new_id, "$network_kill_full" );
01728
01729 success = true;
01730
01731 senderID.SetID( new_id );
01732
01733 sn_Connections [ new_id ].socket = sn_Connections[MAXCLIENTS+1].socket;
01734 peers [ new_id ] = peers[MAXCLIENTS+1];
01735 timeouts [ new_id ] = kickOnDemandTimeout/2;
01736
01737
01738
01739
01740
01741 sn_Connections [ new_id ].supportedAuthenticationMethods_ = supportedAuthenticationMethods;
01742
01743
01744 CountSameIP( new_id, true );
01745 }
01746 }
01747
01748
01749 tOutput o;
01750 o.SetTemplateParameter(1, peers[m.SenderID()].ToString() );
01751 o.SetTemplateParameter(2, sn_Connections[m.SenderID()].socket->GetAddress().ToString() );
01752 o << "$network_server_login";
01753 con << o;
01754 }
01755 if (success)
01756 {
01757 tOutput o;
01758 o.SetTemplateParameter(1, new_id);
01759 o << "$network_server_login_success";
01760 con << o;
01761
01762
01763
01764 sn_Connections[new_id].ping.Reset();
01765 sn_Connections[new_id].bandwidthControl_.Reset();
01766 reset_last_acks(new_id);
01767
01768 if (rate>sn_maxRateOut)
01769 rate=sn_maxRateOut;
01770
01771 sn_Connections[new_id].bandwidthControl_.SetRate( rate );
01772 sn_Connections[new_id].version = version;
01773
01774 nWaitForAck::AckAllPeer(MAXCLIENTS+1);
01775 reset_last_acks(MAXCLIENTS+1);
01776 if (sn_Connections[MAXCLIENTS+1].ackMess)
01777 {
01778 sn_Connections[MAXCLIENTS+1].ackMess=NULL;
01779 }
01780
01781
01782 nMessage *rep=new nMessage(login_accept);
01783 rep->Write(new_id);
01784 (*rep) << sn_myVersion;
01785 (*rep) << peers[m.SenderID()].ToString();
01786 nKrawall::WriteScrambledPassword( salt, *rep );
01787
01788 rep->Send(new_id, -killTimeout);
01789
01790 nMessage::SendCollected( new_id );
01791
01792 nConfItemBase::s_SendConfig(true, new_id);
01793
01794
01795 nMachine & machine = nMachine::GetMachine( new_id );
01796 machine.AddPlayer();
01797 machine.RemovePlayer();
01798
01799 nCallbackLoginLogout::UserLoggedIn(new_id);
01800
01801
01802
01803 }
01804 else if (m.SenderID()==MAXCLIENTS+1)
01805 {
01806 sn_DisconnectUser(MAXCLIENTS+1, "$network_kill_full");
01807 }
01808
01809 sn_UpdateCurrentVersion();
01810
01811 return new_id;
01812 }
01813
01814 void login_handler_1(nMessage& m)
01815 {
01816 unsigned short rate;
01817
01818 m.Read( rate );
01819
01820 if ( !m.End() ){
01821 tString rem_bb;
01822 m >> rem_bb;
01823 }
01824
01825 login_handler( m, rate );
01826 }
01827
01828 void login_handler_2(nMessage& m)
01829 {
01830 unsigned short rate;
01831 unsigned short bb;
01832
01833 m.Read( rate );
01834 m.Read( bb );
01835 tString rem_bb;
01836
01837 if ( bb )
01838 {
01839 m >> rem_bb;
01840 }
01841
01842 int new_ID = login_handler( m, rate );
01843
01844 if ( new_ID > 0 )
01845 {
01846 nMessage* m = tNEW( nMessage )( versionControl );
01847 (*m) << sn_currentVersion;
01848
01849 m->Send( new_ID );
01850
01851 if ( bb )
01852 {
01853 std::ofstream s;
01854 if ( tDirectories::Var().Open(s, "big_brother",std::ios::app) )
01855 s << rem_bb << '\n';
01856 }
01857 }
01858 }
01859
01860
01861 void logout_handler(nMessage &m){
01862 unsigned short id = m.SenderID();
01863
01864
01865 if (sn_Connections[id].socket)
01866 {
01867 tOutput o;
01868 o.SetTemplateParameter(1, id);
01869 o << "$network_logout_server";
01870 con << o;
01871 }
01872 nWaitForAck::AckAllPeer(id);
01873
01874 if (0<id && id<=MAXCLIENTS)
01875 {
01876 sn_DisconnectUser(id, "$network_kill_logout");
01877 }
01878 }
01879
01880
01881 #define MAX_MESS_LEN 300
01882 #define OVERHEAD 32
01883
01884 static REAL sn_OrderPriority = 0;
01885
01886
01887 int sn_SentBytes = 0;
01888 int sn_SentPackets = 0;
01889 int sn_ReceivedBytes = 0;
01890 int sn_ReceivedPackets = 0;
01891 nTimeRolling sn_StatsTime = 0;
01892
01893
01894
01895 void nSendBuffer::AddMessage ( nMessage& message, nBandwidthControl* control )
01896 {
01897 unsigned long id = message.MessageID();
01898 unsigned short len = message.DataLen();
01899 tRecorderSync< unsigned long >::Archive( "_MESSAGE_ID_SEND", 5, id );
01900
01901 sendBuffer_[sendBuffer_.Len()]=htons(message.Descriptor());
01902
01903 sendBuffer_[sendBuffer_.Len()]=htons(message.MessageID());
01904
01905 sendBuffer_[sendBuffer_.Len()]=htons(message.DataLen());
01906 for(int i=0;i<len;i++)
01907 sendBuffer_[sendBuffer_.Len()]=htons(message.Data(i));
01908
01909 tRecorderSync< unsigned short >::Archive( "_MESSAGE_SEND_LEN", 5, len );
01910
01911 if ( control )
01912 {
01913 control->Use( nBandwidthControl::Usage_Planning, len * 2 );
01914 }
01915 }
01916
01917
01918 void nSendBuffer::Send ( nSocket const & socket
01919 , const nAddress & peer
01920 ,nBandwidthControl* control )
01921 {
01922 if (sendBuffer_.Len()){
01923 sn_SentPackets++;
01924 sn_SentBytes += sendBuffer_.Len() * 2 + OVERHEAD;
01925
01926
01927 sendBuffer_[sendBuffer_.Len()]=htons(::sn_myNetID);
01928
01929 socket.Write( reinterpret_cast<int8 *>(&(sendBuffer_[0])),
01930 2*sendBuffer_.Len(), peer);
01931
01932 if ( control )
01933 {
01934 control->Use( nBandwidthControl::Usage_Execution, 2*sendBuffer_.Len() + OVERHEAD );
01935 }
01936
01937 this->Clear();
01938 }
01939 }
01940
01941
01942 void nSendBuffer::Broadcast ( nSocket const & socket
01943 , int port
01944 , nBandwidthControl* control )
01945 {
01946 if (sendBuffer_.Len()){
01947 sn_SentPackets++;
01948 sn_SentBytes += sendBuffer_.Len() * 2 + OVERHEAD;
01949
01950
01951 sendBuffer_[sendBuffer_.Len()]=htons(::sn_myNetID);
01952
01953 socket.Broadcast( reinterpret_cast<int8 *>(&(sendBuffer_[0])),
01954 2*sendBuffer_.Len(), port);
01955
01956 Clear();
01957
01958 if ( control )
01959 {
01960 control->Use( nBandwidthControl::Usage_Execution, 2*sendBuffer_.Len() + OVERHEAD );
01961 }
01962 }
01963 }
01964
01965
01966 void nSendBuffer::Clear()
01967 {
01968 for(int i=sendBuffer_.Len()-1;i>=0;i--)
01969 sendBuffer_(i)=0;
01970
01971 sendBuffer_.SetLen( 0 );
01972 }
01973
01974
01975 nBandwidthControl::nBandwidthControl( nBandwidthControl* parent )
01976 {
01977 #ifdef DEBUG
01978 if ( parent )
01979 parent->numChildren_ ++;
01980 numChildren_ = 0;
01981 #endif
01982
01983 parent_ = parent;
01984
01985 Reset();
01986 }
01987
01988 nBandwidthControl::~nBandwidthControl()
01989 {
01990 #ifdef DEBUG
01991 if ( parent_ )
01992 parent_->numChildren_ --;
01993
01994 tASSERT( numChildren_ == 0 );
01995 #endif
01996 }
01997
01998 void nBandwidthControl::Reset()
01999 {
02000 rateControlPlanned_ = rateControl_ = 1000.0f;
02001 rate_ = 8;
02002 }
02003
02004 void nBandwidthControl::Use( Usage planned, REAL bandwidth )
02005 {
02006 tRecorderSync< REAL >::Archive( "_RATE_CONTROL_USAGE", 4, bandwidth );
02007 ( Usage_Planning == planned ? rateControlPlanned_ : rateControl_ ) -= bandwidth;
02008 }
02009
02010 void nBandwidthControl::Update( REAL ts)
02011 {
02012 tRecorderSync< REAL >::Archive( "_RATE_CONTROL", 12, rateControl_ );
02013 tRecorderSync< REAL >::Archive( "_RATE_CONTROL_PLANNED", 12, rateControlPlanned_ );
02014
02015 rateControl_ += ( rate_ * 1000 ) * ts;
02016
02017 if ( rateControl_ > 1000.0f )
02018 {
02019 rateControl_ = 1000.0f;
02020 }
02021
02022 rateControlPlanned_ = rateControl_;
02023 }
02024
02025 void nMessage::SendCollected(int peer)
02026 {
02027
02028
02029
02030 sn_OrderPriority = 0;
02031
02032 if (peer<0 || peer > MAXCLIENTS+1 || !sn_Connections[peer].socket)
02033 tERR_ERROR("Invalid peer!");
02034
02035 sn_Connections[peer].sendBuffer_.Send( *sn_Connections[peer].socket, peers[peer], &sn_Connections[peer].bandwidthControl_ );
02036 }
02037
02038
02039 void nMessage::BroadcastCollected(int peer, unsigned int port){
02040 if (peer<0 || peer > MAXCLIENTS+1 || !sn_Connections[peer].socket)
02041 tERR_ERROR("Invalid peer!");
02042
02043 sn_Connections[peer].sendBuffer_.Broadcast( *sn_Connections[peer].socket, port, &sn_Connections[peer].bandwidthControl_ );
02044 }
02045
02046
02047
02048 void nMessage::SendImmediately(int peer,bool ack){
02049 if (ack)
02050 {
02051 #ifdef NO_ACK
02052 tASSERT(messageIDBig_);
02053 #endif
02054 new nWaitForAck(this,peer);
02055 }
02056
02057
02058 if ( sn_GetNetState() == nSERVER && peer == 0 && ack )
02059 {
02060 st_Breakpoint();
02061 tJUST_CONTROLLED_PTR< nMessage > bounce(this);
02062 return;
02063 }
02064
02065 #ifdef DEBUG
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081 if (peer==MAXCLIENTS+1){
02082 #ifdef DEBUG
02083 if(descriptor==s_Acknowledge.id)
02084 con << "Sending ack to login slot.\n";
02085 #endif
02086
02087
02088 }
02089 #endif
02090
02091 if (sn_Connections[peer].sendBuffer_.Len()+data.Len()+3 > MAX_MESS_LEN/2){
02092 SendCollected(peer);
02093
02094 }
02095
02096
02097 if (sn_Connections[peer].socket)
02098 {
02099 sn_Connections[peer].sendBuffer_.AddMessage( *this, &sn_Connections[peer].bandwidthControl_ );
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124 if (deb_net)
02125 con << "Sent " <<descriptor << ':' << messageIDBig_ << ":"
02126 << peer << '\n';
02127 }
02128
02129 tControlledPTR< nMessage > bounce( this );
02130 }
02131
02132 REAL sent_per_messid[MAXDESCRIPTORS+100];
02133
02134 void nMessage::Send(int peer,REAL priority,bool ack){
02135 #ifdef NO_ACK
02136 if (!ack)
02137 messageIDBig_ = 0;
02138 #endif
02139
02140
02141 if ( sn_GetNetState() == nSERVER && peer == 0 && ack )
02142 {
02143 st_Breakpoint();
02144 tJUST_CONTROLLED_PTR< nMessage > bounce(this);
02145 return;
02146 }
02147
02148 #ifdef DEBUG
02149
02150 if (peer==MAXCLIENTS+1){
02151 if(descriptor==s_Acknowledge.id)
02152 con << "Sending ack to login slot.\n";
02153
02154
02155 }
02156 #endif
02157
02158 #ifdef DEBUG_X
02159 if (descriptor>1)
02160 con << "PMT " << descriptor << "\n";
02161 #endif
02162
02163
02164
02165
02166 sent_per_messid[descriptor]+=2*(data.Len()+3);
02167
02168 tASSERT(Descriptor()!=s_Acknowledge.ID() || !ack);
02169
02170 new nMessage_planned_send(this,priority+sn_OrderPriority,ack,peer);
02171 sn_OrderPriority += .01;
02172 }
02173
02174
02175 class nAckMessage: public nMessage
02176 {
02177 public:
02178 nAckMessage(): nMessage( s_Acknowledge ){ messageIDBig_ = 0; }
02179 };
02180
02181
02182
02183 typedef std::deque< tJUST_CONTROLLED_PTR< nMessage > > nMessageFifo;
02184
02185 static void rec_peer(unsigned int peer){
02186 tASSERT( sn_Connections[peer].socket );
02187
02188 nMachine::Expire();
02189
02190
02191
02192 static nMessageFifo receivedMessages;
02193
02194
02195 const int serverMaxAcceptedSize=2000;
02196 static tArray< unsigned short > storage(2000);
02197 int maxrec = 0; maxrec = storage.Len();
02198 unsigned short * buff = 0; buff = &storage[0];
02199
02200
02201 if (sn_Connections[peer].socket){
02202 int count=0;
02203 int len=1;
02204 while (len>=0 && sn_Connections[peer].socket)
02205 {
02206 nAddress addrFrom;
02207 len = sn_Connections[peer].socket->Read( reinterpret_cast<int8 *>(buff),maxrec*2, addrFrom);
02208
02209 if (len>0){
02210 if ( len >= maxrec*2 )
02211 {
02212
02213 if ( sn_GetNetState() != nSERVER || len < serverMaxAcceptedSize )
02214 {
02215
02216
02217 storage[maxrec*2-1]=0;
02218 maxrec = storage.Len();
02219 buff = &storage[0];
02220
02221 tERR_WARN( "Oversized network packet received. Read buffer has been enlargened to catch it the next time.");
02222
02223
02224
02225
02226 continue;
02227 }
02228 else
02229 {
02230
02231 sn_DisconnectUser( peer, "$network_kill_error" );
02232 }
02233 }
02234
02235 unsigned short *b=buff;
02236 unsigned short *bend=buff+(len/2-1);
02237
02238 sn_ReceivedPackets++;
02239 sn_ReceivedBytes += len + OVERHEAD;
02240
02241 unsigned short claim_id=ntohs(*bend);
02242
02243
02244 if ( claim_id > MAXCLIENTS+1 )
02245 continue;
02246
02247
02248
02249
02250
02251 count ++;
02252
02253 unsigned int id=peer;
02254
02255 int comp=nAddress::Compare( addrFrom, peers[claim_id] );
02256 if ( comp == 0 )
02257 {
02258
02259 id = claim_id;
02260 }
02261 else
02262 {
02263
02264 id = MAXCLIENTS+1;
02265 peers[ MAXCLIENTS+1 ] = addrFrom;
02266 sn_Connections[ MAXCLIENTS+1 ].socket = sn_Connections[peer].socket;
02267 }
02268
02269
02270
02271 int lenleft = bend - b;
02272
02273 #ifndef NOEXCEPT
02274 try
02275 {
02276 #endif
02277 while( lenleft > 0 ){
02278 tJUST_CONTROLLED_PTR< nMessage > pmess;
02279 pmess = tNEW( nMessage )(b,id,lenleft);
02280 nMessage& mess = *pmess;
02281
02282 lenleft = bend - b;
02283
02284 bool mess_is_new=true;
02285
02286 unsigned short mess_id=mess.MessageID();
02287
02288 #ifdef DEBUG
02289 if ( (simulate_loss && rand()%simulate_loss==0)){
02290
02291 con << "Losing packet " << mess_id << ":" << id << ".\n";
02292 }else
02293 #endif
02294 if(
02295
02296
02297 ( sn_GetNetState() != nSERVER && !login_succeeded && !nCallbackAcceptPackedWithoutConnection::Accept( mess ) )
02298
02299 )
02300 {
02301
02302 }
02303 else
02304 {
02305 if (id <= MAXCLIENTS && mess_id != 0)
02306 {
02307 unsigned short diff=mess_id-highest_ack[id];
02308 if (diff>0 && diff<10000 ||
02309 ((
02310 mess.Descriptor() == login_accept.ID() ||
02311 mess.Descriptor() == login_deny.ID() ||
02312 mess.Descriptor() == login.ID()
02313 ) && highest_ack[id] == 0)
02314 ){
02315
02316
02317 highest_ack[id]=mess_id;
02318 }
02319 else{
02320
02321 for(int i=ACKBACK-1;i>=0;i--)
02322 if (mess_id==lastacks[id][i])
02323 mess_is_new=false;
02324 }
02325 }
02326
02327
02328
02329
02330
02331
02332 if ((!sn_Connections[id].socket))
02333 {
02334 sn_Connections[id].ackMess=NULL;
02335 }
02336 else if (
02337 #ifdef NO_ACK
02338 (mess.MessageID()) &&
02339 #endif
02340 (mess.Descriptor()!=login_ignore.ID() ||
02341 login_succeeded )){
02342
02343
02344 #ifdef DEBUG
02345 if ( id > MAXCLIENTS )
02346 {
02347 con << "Sending ack to login slot.\n";
02348 }
02349 #endif
02350
02351 if(sn_Connections[id].ackMess==NULL)
02352 {
02353 sn_Connections[id].ackMess=new nAckMessage();
02354 }
02355
02356 sn_Connections[id].ackMess->Write(mess.MessageID());
02357 if (sn_Connections[id].ackMess->DataLen()>100){
02358 sn_Connections[id].ackMess->Send(id, 0, false);
02359 sn_Connections[id].ackMess=NULL;
02360 }
02361 }
02362
02363 if (mess_is_new){
02364
02365 if (mess_id > 0)
02366 {
02367 lastacks[id][lastackPos[id]]=mess_id;
02368 if(++lastackPos[id]>=ACKBACK) lastackPos[id]=0;
02369 }
02370
02371
02372
02373
02374
02375
02376
02377
02378 if (sn_GetNetState() != nSTANDALONE)
02379 {
02380
02381 receivedMessages.push_back( pmess );
02382 }
02383 }
02384
02385
02386 }
02387 }
02388 #ifndef NOEXCEPT
02389 }
02390
02391 catch(nKillHim)
02392 {
02393 con << "nKillHim signal caught.\n";
02394 sn_DisconnectUser(peer, "$network_kill_error");
02395 }
02396 #endif
02397 }
02398 #ifndef NOEXCEPT
02399 try
02400 {
02401 #endif
02402 static int recursionCount = 0;
02403 ++recursionCount;
02404
02405
02406 while ( receivedMessages.begin() != receivedMessages.end() )
02407 {
02408 tJUST_CONTROLLED_PTR< nMessage > mess = receivedMessages.front();
02409 receivedMessages.pop_front();
02410
02411
02412 if ( sn_Connections[ mess->SenderID() ].socket )
02413 nDescriptor::HandleMessage( *mess );
02414 }
02415
02416 if ( --recursionCount <= 0 )
02417 {
02418 nCallbackReceivedComplete::ReceivedComplete();
02419 }
02420
02421 #ifndef NOEXCEPT
02422 }
02423
02424 catch(nKillHim const &)
02425 {
02426 con << "nKillHim signal caught.\n";
02427 sn_DisconnectUser(peer, "$network_kill_error");
02428 }
02429 #endif
02430
02431 }
02432 }
02433 }
02434
02435
02436 void sn_ReceiveFromControlSocket()
02437 {
02438 rec_peer(0);
02439 }
02440
02441
02442 void sn_DiscardFromControlSocket()
02443 {
02444
02445
02446 if ( sn_Connections[0].socket )
02447 {
02448 int8 buff[2];
02449 nAddress addrFrom;
02450 sn_Connections[0].socket->Read( reinterpret_cast<int8 *>(buff),0, addrFrom);
02451 }
02452 }
02453
02454
02455 nNetState sn_GetNetState(){
02456 return current_state;
02457 }
02458
02459 void clear_owners();
02460
02461
02462 static bool sn_Listen( unsigned int & net_hostport, const tString& net_hostip )
02463 {
02464 unsigned int net_hostport_before = net_hostport;
02465
02466 try
02467 {
02468 nSocketListener & listener = sn_BasicNetworkSystem.AccessListener();
02469
02470 listener.SetIpList( net_hostip );
02471
02472 bool reported = false;
02473
02474
02475 while ( net_hostport < sn_serverPort + 100 )
02476 {
02477 if ( listener.SetPort( net_hostport ).Listen( true ) )
02478 return true;
02479
02480 if ( !reported )
02481 {
02482 con << "sn_SetNetState: Unable to open accept socket on desired port " << net_hostport << ", Trying next ports...\n";
02483 reported = true;
02484 }
02485
02486 net_hostport++;
02487 }
02488
02489 con << "sn_SetNetState: Giving up setting up listening sockets for IP list " << net_hostip << ".\n";
02490 }
02491 catch( const tException & e )
02492 {
02493 con << "sn_SetNetState: can't setup listening sockets. Reason given:\n"
02494 << e.GetName() << ": " << e.GetDescription() << "\n";
02495 }
02496
02497
02498 net_hostport = net_hostport_before;
02499
02500 return false;
02501 }
02502
02503
02504 static void sn_SaveMachines();
02505 static void sn_LoadMachines();
02506
02507 static void sn_DisconnectAll()
02508 {
02509 for(int i=MAXCLIENTS+1;i>=0;i--)
02510 {
02511 if( sn_Connections[i].socket )
02512 {
02513 sn_DisconnectUser(i, "$network_kill_shutdown");
02514 tVERIFY( !sn_Connections[i].socket );
02515 }
02516 }
02517 nCallbackLoginLogout::UserLoggedOut(0);
02518 }
02519
02520
02521 static bool sn_noReset = false;
02522 nSocketResetInhibitor::nSocketResetInhibitor()
02523 {
02524 sn_noReset = true;
02525 }
02526 nSocketResetInhibitor::~nSocketResetInhibitor()
02527 {
02528 sn_noReset = false;
02529 }
02530
02531 void sn_SetNetState(nNetState x){
02532 static bool reentry=false;
02533 if(!reentry && x!=current_state){
02534 sn_UpdateCurrentVersion();
02535
02536
02537 unsigned int net_hostport = sn_serverPort;
02538
02539
02540 if ( x == nSERVER )
02541 sn_LoadMachines();
02542 else if ( current_state == nSERVER )
02543 if ( !tRecorder::IsPlayingBack() )
02544 sn_SaveMachines();
02545
02546 reentry=true;
02547 if (x!=nSTANDALONE)
02548 {
02549 if (x==nCLIENT)
02550 {
02551 sn_DisconnectAll();
02552 }
02553 else
02554 {
02555 sn_myNetID=0;
02556 }
02557
02558 if (!sn_Connections[0].socket)
02559 sn_Connections[0].socket=sn_BasicNetworkSystem.Init();
02560
02561 if (x == nSERVER)
02562 {
02563
02564 sn_Listen( net_hostport, net_hostip ) ||
02565 sn_Listen( net_hostport, tString( "ANY" ) ) ||
02566 sn_Listen( net_hostport, tString( "ALL" ) );
02567
02568 #ifdef DEDICATED
02569
02570 sn_serverPort = net_hostport;
02571 #endif
02572 }
02573 }
02574 else
02575 {
02576 clear_owners();
02577 for(int i=MAXCLIENTS+1;i>=0;i--){
02578 if(sn_Connections[i].socket){
02579 if (i==0 && current_state!=nSERVER)
02580 {
02581 con << tOutput("$network_logout_process");
02582 for(int j=3;j>=0;j--){
02583 nMessage *lo=new nMessage(logout);
02584 lo->Write(static_cast<unsigned short>(sn_myNetID));
02585 lo->ClearMessageID();
02586 lo->SendImmediately(0, false);
02587 nMessage::SendCollected(0);
02588 tDelay(1000);
02589 }
02590 con << tOutput("$network_logout_done");
02591
02592 sn_myNetID=0;
02593 }
02594 }
02595 sn_DisconnectUserNoWarn(i, "$network_kill_shutdown");
02596 }
02597
02598 sn_Connections[0].socket = 0;
02599
02600
02601 if ( !sn_noReset )
02602 sn_BasicNetworkSystem.Shutdown();
02603 }
02604
02605 current_state=x;
02606 reentry=false;
02607 }
02608
02609 sn_UpdateCurrentVersion();
02610 }
02611
02612
02613
02614
02615
02616
02617 void sn_Bend( nAddress const & address )
02618 {
02619 if ((sn_GetNetState() == nSTANDALONE))
02620 sn_SetNetState(nCLIENT);
02621
02622 peers[0] = address;
02623 }
02624
02625 void sn_Bend( tString const & server, unsigned int port)
02626 {
02627
02628 nAddress address;
02629 address.SetHostname( server );
02630 address.SetPort( port );
02631
02632
02633 sn_Bend( address );
02634 }
02635
02636 nConnectError sn_Connect( nAddress const & server, nLoginType loginType, nSocket const * socket ){
02637 sn_DenyReason = "";
02638
02639
02640 sn_redirectTo.release();
02641
02642
02643 nPingAverager::SetWeight(.0001);
02644
02645
02646
02647 sn_SetNetState(nSTANDALONE);
02648 sn_SetNetState(nCLIENT);
02649
02650
02651 if ( socket )
02652 sn_Connections[0].socket = socket;
02653
02654 sn_Connections[0].ping.Reset();
02655
02656 peers[0] = server;
02657
02658 reset_last_acks(0);
02659 nCallbackLoginLogout::UserLoggedOut(0);
02660 sn_Connections[0].sendBuffer_.Clear();
02661
02662 tASSERT( sn_Connections[0].socket );
02663
02664
02665 sn_Connections[0].bandwidthControl_.SetRate( sn_maxRateOut );
02666
02667 sn_myNetID=0;
02668
02669
02670 sn_Receive();
02671 sn_Receive();
02672 sn_Receive();
02673
02674
02675 sn_currentVersion = nVersion(0,0);
02676
02677
02678 tJUST_CONTROLLED_PTR< nMessage > mess;
02679 if ( loginType != Login_Pre0252 )
02680 {
02681 mess=new nMessage(login_2);
02682 mess->Write(sn_maxRateIn);
02683
02684 unsigned short bb = big_brother;
02685 mess->Write( bb );
02686 if ( bb ){
02687 (*mess) << sn_bigBrotherString;
02688 big_brother=false;
02689 }
02690 }
02691 else
02692 {
02693 mess=new nMessage(login);
02694 mess->Write(sn_maxRateIn);
02695
02696
02697 if (big_brother)
02698 {
02699 (*mess) << sn_bigBrotherString;
02700 }
02701 else
02702 {
02703 (*mess) << tString("");
02704 }
02705
02706 big_brother=false;
02707 }
02708
02709
02710 (*mess) << sn_MyVersion();
02711
02712
02713 (*mess) << nKrawall::nMethod::SupportedMethods();
02714
02715
02716 nKrawall::RandomSalt( loginSalt );
02717 nKrawall::WriteScrambledPassword( loginSalt, *mess );
02718
02719 mess->ClearMessageID();
02720 mess->SendImmediately(0,false);
02721 nMessage::SendCollected(0);
02722
02723 con << tOutput("$network_login_process");
02724
02725 login_failed=false;
02726 login_succeeded=false;
02727
02728 nTimeRolling timeout=tSysTimeFloat()+5;
02729
02730 static REAL resend = .25;
02731 nTimeAbsolute nextSend = tSysTimeFloat() + resend/5;
02732 while(sn_GetNetState()==nCLIENT && tSysTimeFloat()<timeout &&
02733 !login_failed && !login_succeeded){
02734 if ( tSysTimeFloat() > nextSend )
02735 {
02736
02737 nextSend = tSysTimeFloat() + resend;
02738 mess->SendImmediately(0,false);
02739 nMessage::SendCollected(0);
02740 }
02741
02742 tAdvanceFrame(10000);
02743 sn_Receive();
02744 sn_SendPlanned();
02745
02746
02747 if ( tConsole::Idle() )
02748 {
02749 con << tOutput("$network_login_failed_abort");
02750 sn_SetNetState(nSTANDALONE);
02751 return nABORT;
02752 }
02753 }
02754 if (login_failed)
02755 {
02756 con << tOutput("$network_login_failed");
02757 sn_SetNetState(nSTANDALONE);
02758 return nDENIED;
02759 }
02760 else if (tSysTimeFloat()>=timeout || sn_GetNetState()!=nCLIENT){
02761 if ( loginType == Login_All )
02762 {
02763 return sn_Connect( server, Login_Pre0252, socket );
02764 }
02765 else
02766 {
02767 con << tOutput("$network_login_failed_timeout");
02768 sn_SetNetState(nSTANDALONE);
02769 return nTIMEOUT;
02770 }
02771 }
02772 else{
02773 nCallbackLoginLogout::UserLoggedIn(0);
02774
02775 tOutput mess;
02776 mess.SetTemplateParameter(1, sn_myNetID);
02777 mess << "$network_login_success";
02778 con << mess;
02779 con << tOutput("$network_login_sync");
02780 sn_Sync(40);
02781 con << tOutput("$network_login_relabeling");
02782 con << tOutput("$network_login_sync2");
02783 sn_Sync(40,true);
02784 con << tOutput("$network_login_done");
02785
02786
02787 nPingAverager::SetWeight(1);
02788
02789 return nOK;
02790 }
02791 }
02792
02793
02794 void nReadError( bool critical )
02795 {
02796
02797 #ifndef NOEXCEPT
02798 if ( critical )
02799 throw nKillHim();
02800 else
02801 throw nIgnore();
02802 #else
02803 con << "\nI told you not to use PGCC! Now we need to leave the\n"
02804 << "system in an undefined state. The progam will crash now.\n"
02805 << "\n\n";
02806 #endif
02807 }
02808
02809 #ifdef DEDICATED
02810 static short sn_decorateID = true;
02811 static tConfItem< short > sn_decorateIDConf( "CONSOLE_DECORATE_ID", sn_decorateID );
02812
02813 static short sn_decorateIP = false;
02814 static tConfItem< short > sn_decorateIPConf( "CONSOLE_DECORATE_IP", sn_decorateIP );
02815
02816
02817 class nConsoleFilter:public tConsoleFilter{
02818 private:
02819 virtual void DoFilterLine( tString &line )
02820 {
02821 if ( sn_decorateID )
02822 {
02823 tString orig = line;
02824
02825 int id = nCurrentSenderID::GetID();
02826 bool printIP = ( id > 0 && sn_decorateIP );
02827
02828 line = "";
02829 line << "[";
02830 if ( sn_decorateID )
02831 line << id;
02832 if ( sn_decorateID && printIP )
02833 line << " ";
02834 if ( printIP )
02835 {
02836
02837 tString IP;
02838 sn_GetAdr( id, IP );
02839 line << "IP=" << IP;
02840 }
02841
02842 line << "] " << orig;
02843 }
02844 }
02845 };
02846
02847 static nConsoleFilter sn_consoleFilter;
02848 #endif
02849
02850 static void sn_ConsoleOut_handler(nMessage &m){
02851 if (sn_GetNetState()!=nSERVER){
02852 tString s;
02853 m >> s;
02854 con << s;
02855 }
02856 }
02857
02858
02859 static nDescriptor sn_ConsoleOut_nd(8,sn_ConsoleOut_handler,"sn_ConsoleOut");
02860
02861
02862 nMessage* sn_ConsoleOutMessage( const tOutput& o )
02863 {
02864 tString message(o);
02865 message << "0xffffff";
02866
02867
02868 static const int maxLen = 1400;
02869 static bool recurse = true;
02870 if ( message.Len() > maxLen && recurse )
02871 {
02872 recurse = false;
02873 tERR_WARN( "Long console message truncated.");
02874
02875 message.SetLen( maxLen+1 );
02876 message[maxLen]='\0';
02877 recurse = false;
02878 }
02879
02880 nMessage* m=new nMessage(sn_ConsoleOut_nd);
02881 *m << message;
02882
02883 return m;
02884 }
02885
02886 void sn_ConsoleOut(const tOutput& o,int client){
02887
02888
02889 tJUST_CONTROLLED_PTR< nMessage > m = sn_ConsoleOutMessage( o );
02890
02891 if (client<0){
02892 m->BroadCast();
02893 con << o;
02894 }
02895 else if (client==sn_myNetID)
02896 {
02897 con << o;
02898 }
02899 else
02900 m->Send(client);
02901 }
02902
02903 static void client_cen_handler(nMessage &m){
02904 if (sn_GetNetState()!=nSERVER){
02905 tString s;
02906 m >> s;
02907 con.CenterDisplay(s);
02908 }
02909 }
02910
02911 static nDescriptor client_cen_nd(9,client_cen_handler,"client_cen");
02912
02913
02914 void sn_CenterMessage(const tOutput &o,int client){
02915 tString message(o);
02916
02917 tJUST_CONTROLLED_PTR< nMessage > m=new nMessage(client_cen_nd);
02918 *m << message;
02919 if (client<0){
02920 m->BroadCast();
02921 con.CenterDisplay(message);
02922 }
02923 else if (client==sn_myNetID)
02924 con.CenterDisplay(message);
02925 else
02926 m->Send(client);
02927 }
02928
02929 static void ConsoleOut_conf(std::istream &s)
02930 {
02931
02932 tString message;
02933 message.ReadLine( s, true );
02934
02935 message += "\n";
02936
02937
02938 sn_ConsoleOut( message );
02939 }
02940
02941 static tConfItemFunc ConsoleOut_c("CONSOLE_MESSAGE",&ConsoleOut_conf);
02942 static tAccessLevelSetter sn_ConsoleConfLevel( ConsoleOut_c, tAccessLevel_Moderator );
02943
02944 static void CeterMessage_conf(std::istream &s)
02945 {
02946
02947 tString message;
02948 message.ReadLine( s, true );
02949
02950
02951 sn_CenterMessage( message );
02952 }
02953
02954 static tConfItemFunc CenterMessage_c("CENTER_MESSAGE",&CeterMessage_conf);
02955 static tAccessLevelSetter sn_CenterConfLevel( CenterMessage_c, tAccessLevel_Moderator );
02956
02957
02958
02959
02960
02961
02962 tHeap<planned_send> send_queue[MAXCLIENTS+2];
02963
02964 planned_send::planned_send(REAL priority,int Peer){
02965 peer=Peer;
02966
02967 SetVal( priority, send_queue[peer] );
02968 }
02969
02970 planned_send::~planned_send(){
02971 RemoveFromHeap();
02972 }
02973
02974 tHeapBase *planned_send::Heap() const
02975 {
02976 return &send_queue[peer];
02977 }
02978
02979
02980 void planned_send::add_to_priority(REAL diff)
02981 {
02982 SetVal( Val() + diff, send_queue[peer] );
02983 }
02984
02985
02986
02987 nMessage_planned_send::nMessage_planned_send
02988 (nMessage *M,REAL priority,bool Ack,int Peer)
02989 :planned_send(priority,Peer),m(M),ack(Ack){
02990
02991 }
02992
02993 nMessage_planned_send::~nMessage_planned_send(){
02994 }
02995
02996 void nMessage_planned_send::execute(){
02997 if ( Val() < -killTimeout-10){
02998 tOutput mess;
02999 mess.SetTemplateParameter(1, peer);
03000 mess << "$network_error_overflow";
03001 con << mess;
03002 st_Breakpoint();
03003 sn_DisconnectUser(peer, "$network_kill_overflow");
03004 }
03005 else if (m)
03006 m->SendImmediately(peer,ack);
03007 }
03008
03009
03010
03011
03012 static REAL sn_SendPlanned1(){
03013 sn_OrderPriority = 0;
03014
03015
03016 static double lastTime=-1;
03017 nTimeAbsolute time=tSysTimeFloat();
03018 if (lastTime<0)
03019 lastTime=time;
03020
03021 if (time<lastTime-.01 || time>lastTime+1000)
03022 #ifdef DEBUG
03023 {
03024 tERR_ERROR("Timer hickup!");
03025 }
03026 #else
03027 {
03028 tERR_WARN("Timer hickup!");
03029 lastTime=time;
03030 }
03031 #endif
03032 REAL dt = time - lastTime;
03033
03034
03035 for(int i=0;i<=MAXCLIENTS+1;i++){
03036 nConnectionInfo & connection = sn_Connections[i];
03037 if ( !connection.socket )
03038 continue;
03039
03040 while (connection.ackPending<sn_maxNoAck &&
03041 connection.bandwidthControl_.CanSend() &&
03042 send_queue[i].Len())
03043 {
03044 send_queue[i](0)->execute();
03045 if (send_queue[i].Len())
03046 delete send_queue[i](0);
03047 }
03048
03049
03050 for(int j=send_queue[i].Len()-1;j>=0;j--)
03051 send_queue[i](j)->add_to_priority(-dt);
03052 }
03053 lastTime=time;
03054
03055 return dt;
03056 }
03057
03058 static void sn_SendPlanned2( REAL dt ){
03059
03060 for(int i=0;i<=MAXCLIENTS+1;i++){
03061 nConnectionInfo & connection = sn_Connections[i];
03062 if ( connection.socket )
03063 {
03064 if (connection.sendBuffer_.Len()>0 && connection.bandwidthControl_.CanSend() )
03065 nMessage::SendCollected(i);
03066
03067
03068 connection.Timestep( dt );
03069 }
03070 }
03071 }
03072
03073 void sn_SendPlanned()
03074 {
03075
03076 REAL dt = sn_SendPlanned1();
03077
03078
03079 for(int i=0;i<=MAXCLIENTS+1;i++)
03080 if(sn_Connections[i].socket && sn_Connections[i].ackMess && !sn_Connections[i].ackMess->End()
03081
03082 && ( sn_Connections[i].bandwidthControl_.CanSend() || sn_Connections[i].sendBuffer_.Len() > 0 )
03083 ){
03084 sn_Connections[i].ackMess->SendImmediately(i, false);
03085 sn_Connections[i].ackMess=NULL;
03086 }
03087
03088
03089 nWaitForAck::Resend();
03090
03091
03092 sn_SendPlanned2( dt );
03093 }
03094
03095 void sn_Receive(){
03096
03097
03098
03099
03100
03101
03102
03103 netTime=tSysTimeFloat();
03104
03105 sn_Connections[MAXCLIENTS+1].ping.Reset();
03106
03107
03108
03109
03110
03111
03112
03113
03114
03115
03116 switch (current_state){
03117 case nSERVER:
03118 {
03119 memset( &peers[0], 0, sizeof(sockaddr) );
03120
03121
03122 nSocketListener const & listener = sn_BasicNetworkSystem.GetListener();
03123 for ( nSocketListener::iterator i = listener.begin(); i != listener.end(); ++i )
03124 {
03125
03126 memset( &peers[MAXCLIENTS+1], 0, sizeof(sockaddr) );
03127
03128 if((sn_Connections[MAXCLIENTS+1].socket = (*i).CheckNewConnection() ) != NULL)
03129 rec_peer(MAXCLIENTS+1);
03130 }
03131 }
03132
03133
03134
03135 break;
03136
03137 case nCLIENT:
03138 rec_peer(0);
03139 break;
03140
03141 case nSTANDALONE:
03142 default:
03143 break;
03144 }
03145
03146
03147
03148
03149
03150
03151
03152
03153 }
03154
03155 void sn_KickUser(int i, const tOutput& reason, REAL severity, nServerInfoBase * redirectTo )
03156 {
03157
03158 con << tOutput( "$network_kill_log", i, reason );
03159
03160
03161 if ( severity > 0 )
03162 {
03163 nMachine::GetMachine(i).OnKick( severity );
03164 }
03165
03166
03167 sn_DisconnectUser( i, reason, redirectTo );
03168 }
03169
03170 void sn_DisconnectUser(int i, const tOutput& reason, nServerInfoBase * redirectTo )
03171 {
03172
03173 if ( i == 0 && sn_GetNetState() == nSERVER )
03174 {
03175 tERR_WARN( "Server tried to disconnect from itself." );
03176 return;
03177 }
03178
03179
03180 if ( i != 0 && sn_GetNetState() == nCLIENT )
03181 {
03182 tERR_ERROR( "Client tried to disconnect from another client: impossible and a bad idea." );
03183 return;
03184 }
03185
03186
03187 if (!sn_Connections[i].socket)
03188 {
03189 return;
03190 }
03191
03192 sn_DisconnectUserNoWarn( i, reason, redirectTo );
03193 }
03194
03195 void sn_DisconnectUserNoWarn(int i, const tOutput& reason, nServerInfoBase * redirectTo )
03196 {
03197 nCurrentSenderID senderID( i );
03198
03199 nWaitForAck::AckAllPeer(i);
03200
03201 static bool reentry=false;
03202 if (reentry)
03203 return;
03204 reentry=true;
03205
03206 bool printMessage = false;
03207
03208 if (sn_Connections[i].socket)
03209 {
03210 nMessage::SendCollected(i);
03211 printMessage = true;
03212
03213
03214 if ( i!=0 && i != MAXCLIENTS+2 && sn_GetNetState() == nSERVER ){
03215 for(int j=2;j>=0;j--){
03216 nMessage* mess = (new nMessage(login_deny));
03217 *mess << tString( reason );
03218
03219
03220 tString redirection;
03221 int port;
03222 if ( redirectTo )
03223 {
03224 redirection = redirectTo->GetConnectionName();
03225 port = redirectTo->GetPort();
03226 }
03227 *mess << redirection;
03228 *mess << port;
03229
03230 mess->SendImmediately(i, false);
03231 nMessage::SendCollected(i);
03232 }
03233 }
03234 }
03235
03236 nWaitForAck::AckAllPeer(i);
03237
03238 sn_Connections[i].ackMess=NULL;
03239
03240 if (i==0 && sn_GetNetState()==nCLIENT)
03241 sn_SetNetState(nSTANDALONE);
03242
03243 reset_last_acks(i);
03244
03245
03246
03247 sn_Connections[i].ackPending=0;
03248
03249
03250 nCallbackLoginLogout::UserLoggedOut(i);
03251
03252 if ( printMessage )
03253 {
03254 con << tOutput( "$network_killuser", i, sn_Connections[i].ping.GetPing() );
03255 }
03256
03257
03258 sn_Connections[i].sendBuffer_.Clear();
03259 sn_Connections[i].socket=NULL;
03260 peers[i] = nAddress();
03261 sn_Connections[i].Clear();
03262 while (send_queue[i].Len())
03263 delete (send_queue[i](0));
03264
03265 reentry=false;
03266
03267 sn_UpdateCurrentVersion();
03268 }
03269
03270
03271 int sn_QueueLen(int user){
03272 return send_queue[user].Len();
03273 }
03274
03275
03276 static tCallback* s_loginoutAnchor=NULL;
03277 int nCallbackLoginLogout::user;
03278 bool nCallbackLoginLogout::login;
03279
03280 nCallbackLoginLogout::nCallbackLoginLogout(AA_VOIDFUNC *f)
03281 :tCallback(s_loginoutAnchor,f){}
03282
03283 void nCallbackLoginLogout::UserLoggedIn(int u){
03284 login = true;
03285 user = u;
03286 Exec(s_loginoutAnchor);
03287 }
03288
03289 void nCallbackLoginLogout::UserLoggedOut(int u){
03290 login = false;
03291 user = u;
03292 Exec(s_loginoutAnchor);
03293 }
03294
03295 unsigned short nCallbackAcceptPackedWithoutConnection::descriptor=0;
03296 static tCallbackOr* s_AcceptAnchor=NULL;
03297
03298 nCallbackAcceptPackedWithoutConnection::nCallbackAcceptPackedWithoutConnection(BOOLRETFUNC *f)
03299 : tCallbackOr( s_AcceptAnchor, f )
03300 {
03301 }
03302
03303 bool nCallbackAcceptPackedWithoutConnection::Accept( const nMessage& m )
03304 {
03305 descriptor=m.Descriptor();
03306 return Exec( s_AcceptAnchor );
03307 }
03308
03309 static tCallback* s_ReceivedCompleteAnchor=NULL;
03310
03311 nCallbackReceivedComplete::nCallbackReceivedComplete(AA_VOIDFUNC *f)
03312 : tCallback( s_ReceivedCompleteAnchor, f )
03313 {
03314 }
03315
03316 void nCallbackReceivedComplete::ReceivedComplete( )
03317 {
03318 Exec( s_ReceivedCompleteAnchor );
03319 }
03320
03321 static bool net_Accept()
03322 {
03323 return
03324 nCallbackAcceptPackedWithoutConnection::Descriptor()==login_accept.ID() ||
03325 nCallbackAcceptPackedWithoutConnection::Descriptor()==login_deny.ID();
03326 }
03327
03328 static nCallbackAcceptPackedWithoutConnection net_acc( &net_Accept );
03329
03330 static void net_exit(){
03331 for (int i=MAXCLIENTS+1;i>=0;i--)
03332 {
03333 sn_Connections[i].ackMess = NULL;
03334 while (send_queue[i].Len())
03335 delete send_queue[i].Remove(0);
03336 }
03337 }
03338
03339 static tInitExit net_ie(NULL, &net_exit);
03340
03341
03342
03343 void sn_Statistics()
03344 {
03345 nTimeRolling time = tSysTimeFloat();
03346 REAL dt = time - sn_StatsTime;
03347 sn_StatsTime = time;
03348
03349 if (dt > 0 && (sn_SentPackets || sn_SentBytes))
03350 {
03351 tOutput o;
03352 o.SetTemplateParameter(1,dt);
03353 o.SetTemplateParameter(2,sn_SentBytes);
03354 o.SetTemplateParameter(3,sn_SentPackets);
03355 o.SetTemplateParameter(4,sn_SentBytes/dt);
03356 o.SetTemplateParameter(5,sn_ReceivedBytes);
03357 o.SetTemplateParameter(6,sn_ReceivedPackets);
03358 o.SetTemplateParameter(7,sn_ReceivedBytes/dt);
03359 o << "$network_statistics1";
03360 o << "$network_statistics2";
03361 o << "$network_statistics3";
03362
03363 con << o;
03364 }
03365
03366 sn_SentPackets = 0;
03367 sn_SentBytes = 0;
03368 sn_ReceivedPackets = 0;
03369 sn_ReceivedBytes = 0;
03370 }
03371
03372
03373
03374
03375
03376
03377 nConnectionInfo::nConnectionInfo(){Clear();}
03378 nConnectionInfo::~nConnectionInfo(){}
03379
03380 void nConnectionInfo::Clear(){
03381 socket = NULL;
03382 ackPending = 0;
03383 ping.Reset();
03384
03385
03386 supportedAuthenticationMethods_ = "";
03387
03388 sendBuffer_.Clear();
03389
03390 bandwidthControl_.Reset();
03391
03392 ackMess = NULL;
03393
03394
03395 packetLoss_.Reset();
03396 packetLoss_.Add(.1,10);
03397 }
03398
03399 void nConnectionInfo::Timestep( REAL dt )
03400 {
03401
03402 ping.Timestep( dt );
03403
03404
03405 bandwidthControl_.Update( dt );
03406
03407
03408 packetLoss_.Timestep( .02 * dt );
03409 }
03410
03411 void nConnectionInfo::ReliableMessageSent()
03412 {
03413 packetLoss_.Add( 1 );
03414 }
03415
03416 void nConnectionInfo::AckReceived()
03417 {
03418 packetLoss_.Add( -1 );
03419 }
03420
03421 REAL nConnectionInfo::PacketLoss() const
03422 {
03423 REAL ret = packetLoss_.GetAverage();
03424 return ret > 0 ? ret : 0;
03425 }
03426
03427 void sn_GetAdr(int user, tString& name)
03428 {
03429 peers[user].ToString( name );
03430 }
03431
03432 unsigned int sn_GetPort(int user)
03433 {
03434 return peers[user].GetPort();
03435 }
03436
03437 unsigned int sn_GetServerPort()
03438 {
03439 return sn_serverPort;
03440 }
03441
03442 int sn_NumUsers( bool all )
03443 {
03444 int ret = 0;
03445 for (int i=MAXCLIENTS; i>0; i--)
03446 if (sn_Connections[i].socket && ( all || ( sn_allowSameIPCountSoft > CountSameIP( i ) ) ) )
03447 ret++;
03448
03449 #ifndef DEDICATED
03450 ret++;
03451 #endif
03452
03453 return ret;
03454 }
03455
03456 int sn_NumUsers()
03457 {
03458 return sn_NumUsers( true );
03459 }
03460
03461 int sn_NumRealUsers()
03462 {
03463 return sn_NumUsers( false );
03464 }
03465
03466 int sn_MaxUsers()
03467 {
03468 return sn_maxClients;
03469 }
03470
03471 int sn_MessagesPending(int user)
03472 {
03473 return sn_Connections[user].ackPending + send_queue[user].Len();
03474 }
03475
03476 nBasicNetworkSystem sn_BasicNetworkSystem;
03477
03478
03479
03480
03481
03482
03485
03486
03487 nKillHim::nKillHim( void )
03488 {
03489 }
03490
03491
03492
03493
03494
03495
03498
03499
03500 nKillHim::~nKillHim( void )
03501 {
03502 }
03503
03504
03505
03506
03507
03508
03512
03513
03514 tString nKillHim::DoGetName( void ) const
03515 {
03516 return tString( "Connektion kill request" );
03517 }
03518
03519
03520
03521
03522
03523
03527
03528
03529 tString nKillHim::DoGetDescription( void ) const
03530 {
03531 return tString( "The currently handled peer must have done something illegal, so it should be terminated." );
03532 }
03533
03534
03535
03536
03537
03538
03541
03542
03543 nIgnore::nIgnore( void )
03544 {
03545 }
03546
03547
03548
03549
03550
03551
03554
03555
03556 nIgnore::~nIgnore( void )
03557 {
03558 }
03559
03560
03561
03562
03563
03564
03568
03569
03570 tString nIgnore::DoGetName( void ) const
03571 {
03572 return tString( "Packet ignore request" );
03573 }
03574
03575
03576
03577
03578
03579
03583
03584
03585 tString nIgnore::DoGetDescription( void ) const
03586 {
03587 return tString( "An error that should lead to the current message getting ingored was detected." );
03588 }
03589
03590
03591
03592
03593
03594
03597
03598
03599 nAverager::nAverager( void )
03600 : weight_(0), sum_(0), sumSquared_(0), weightSquared_(0)
03601 {
03602 }
03603
03604
03605
03606
03607
03608
03611
03612
03613 nAverager::~nAverager( void )
03614 {
03615 }
03616
03617
03618
03619
03620
03621
03625
03626
03627 void nAverager::Timestep( REAL decay )
03628 {
03629 REAL factor = 1/(1+decay);
03630
03631
03632 weight_ *= factor;
03633 sum_ *= factor;
03634 sumSquared_ *= factor;
03635 weightSquared_ *= factor * factor;
03636 }
03637
03638
03639
03640
03641
03642
03647
03648
03649 void nAverager::Add( REAL value, REAL weight )
03650 {
03651 tASSERT( weight >= 0 );
03652 weight_ += weight;
03653 sum_ += weight * value;
03654 sumSquared_ += weight * value * value;
03655 weightSquared_ += weight * weight;
03656 }
03657
03658
03659
03660
03661
03662
03665
03666
03667 void nAverager::Reset( void )
03668 {
03669 weightSquared_ = weight_ = sum_ = sumSquared_ = 0.0f;
03670 }
03671
03672
03673
03674
03675
03676
03680
03681
03682 REAL nAverager::GetAverage( void ) const
03683 {
03684 if ( weight_ > 0 )
03685 return sum_ / weight_;
03686 else
03687 return 0;
03688 }
03689
03690
03691
03692
03693
03694
03698
03699
03700 REAL nAverager::GetDataVariance( void ) const
03701 {
03702 if ( weight_ > 0 )
03703 {
03704 REAL average = sum_ / weight_;
03705 REAL averageSquare = sumSquared_ / weight_;
03706 REAL ret = averageSquare - average * average;
03707 if ( ret < 0 )
03708 ret = 0;
03709 return ret;
03710 }
03711 else
03712 return 0;
03713 }
03714
03715
03716
03717
03718
03719
03723
03724
03725 REAL nAverager::GetAverageVariance( void ) const
03726 {
03727 if ( weight_ > 0 )
03728 {
03729 REAL square = weight_ * weight_;
03730
03731 REAL denominator = square - weightSquared_;
03732 REAL numerator = GetDataVariance() * weightSquared_;
03733 if ( denominator > numerator * 1E-30 )
03734 {
03735 return numerator/denominator;
03736 }
03737 else
03738 return 1E+30;
03739 }
03740 else
03741 return 0;
03742 }
03743
03744
03745
03746
03747
03748
03753
03754
03755 std::istream & nAverager::operator <<( std::istream & stream )
03756 {
03757 char c;
03758 stream >> c;
03759 tASSERT( c == '(' );
03760
03761 stream >> weight_ >> sum_ >> sumSquared_ >> weightSquared_;
03762
03763 stream >> c;
03764 tASSERT( c == ')' );
03765
03766 return stream;
03767 }
03768
03769
03770
03771
03772
03773
03778
03779
03780 std::ostream & nAverager::operator >>( std::ostream & stream ) const
03781 {
03782 stream << '(' << weight_ << ' ' << sum_ << ' ' << sumSquared_ << ' ' << weightSquared_ << ')';
03783
03784 return stream;
03785 }
03786
03787
03788
03789
03790
03791
03797
03798
03799 std::istream & operator >> ( std::istream & stream, nAverager & averager )
03800 {
03801 return averager << stream;
03802 }
03803
03804
03805
03806
03807
03808
03814
03815
03816 std::ostream & operator << ( std::ostream & stream, nAverager const & averager )
03817 {
03818 return averager >> stream;
03819 }
03820
03821
03822
03823
03824
03825
03826
03829
03830
03831 nPingAverager::nPingAverager( void )
03832 {
03833 Reset();
03834 }
03835
03836
03837
03838
03839
03840
03843
03844
03845 nPingAverager::~nPingAverager( void )
03846 {
03847 }
03848
03849
03850
03851
03852
03853
03857
03858
03859 REAL nPingAverager::GetPing( void ) const
03860 {
03861
03862
03863
03864 REAL variance = 1;
03865 {
03866 REAL snailVariance = this->snail_.GetDataVariance();
03867 REAL slowVariance = this->slow_.GetDataVariance();
03868 REAL fastVariance = this->fast_.GetDataVariance();
03869 variance = variance < snailVariance ? variance : snailVariance;
03870 variance = variance < slowVariance ? variance : slowVariance;
03871 variance = variance < fastVariance ? variance : fastVariance;
03872 }
03873
03874 REAL pingSnail = this->GetPingSnail();
03875 REAL pingSlow = this->GetPingSlow();
03876 REAL pingFast = this->GetPingFast();
03877
03878
03879 REAL pingReturn = pingSnail;
03880
03881
03882 if ( ( pingSlow - pingReturn ) * ( pingSlow - pingReturn ) > variance )
03883 {
03884
03885 if ( pingSlow > pingReturn * 2 )
03886 pingSlow = pingReturn * 2;
03887
03888 pingReturn = pingSlow;
03889 }
03890
03891
03892 if ( ( pingFast - pingReturn ) * ( pingFast - pingReturn ) > variance )
03893 {
03894 if ( pingFast > pingReturn * 2 )
03895 pingFast = pingReturn * 2;
03896
03897 pingReturn = pingFast;
03898 }
03899
03900
03901 return pingReturn + sqrtf(variance) * 1.5;
03902 }
03903
03904
03905
03906
03907
03908
03912
03913
03914 nPingAverager::operator REAL( void ) const
03915 {
03916 return GetPing();
03917 }
03918
03919
03920
03921
03922
03923
03927
03928
03929 REAL nPingAverager::GetPingSnail( void ) const
03930 {
03931 return snail_.GetAverage();
03932 }
03933
03934
03935
03936
03937
03938
03942
03943
03944 REAL nPingAverager::GetPingSlow( void ) const
03945 {
03946 return slow_.GetAverage();
03947 }
03948
03949
03950
03951
03952
03953
03957
03958
03959 REAL nPingAverager::GetPingFast( void ) const
03960 {
03961 return fast_.GetAverage();
03962 }
03963
03964
03965
03966
03967
03968
03972
03973
03974 bool nPingAverager::IsSpiking( void ) const
03975 {
03976 REAL difference = slow_.GetAverage() - fast_.GetAverage();
03977 return slow_.GetAverageVariance() < difference * difference;
03978 }
03979
03980
03981
03982
03983
03984
03988
03989
03990 void nPingAverager::Timestep( REAL decay )
03991 {
03992 snail_.Timestep( decay * .02 );
03993 slow_.Timestep ( decay * .2 );
03994 fast_.Timestep ( decay * 2 );
03995 }
03996
03997
03998
03999
04000
04001
04006
04007
04008 void nPingAverager::Add( REAL value, REAL weight )
04009 {
04010
04011 snail_.Add( value, weight );
04012 slow_.Add ( value, weight );
04013 fast_.Add ( value, weight );
04014 }
04015
04016
04017
04018
04019
04020
04024
04025
04026 void nPingAverager::Add( REAL value )
04027 {
04028
04029 Add( value, weight_ );
04030 }
04031
04032
04033
04034
04035
04036
04039
04040
04041 void nPingAverager::Reset( void )
04042 {
04043 snail_.Reset();
04044 slow_. Reset();
04045 fast_. Reset();
04046
04047
04048 Add( 1, .000001 );
04049 Add( 0, .000001 );
04050
04051
04052
04053
04054 }
04055
04056 REAL nPingAverager::weight_=1;
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04069
04070
04071 nMachine::nMachine( void )
04072 : lastUsed_(tSysTimeFloat())
04073 , banned_(-1)
04074 , players_(0)
04075 , decorators_(0)
04076 {
04077 kph_.Add(0,.1666);
04078 lastPlayerAction_ = lastUsed_;
04079 }
04080
04081
04082
04083
04084
04085
04088
04089
04090 nMachine::~nMachine( void )
04091 {
04092
04093 while ( decorators_ )
04094 {
04095 nMachineDecorator * decorator = decorators_;
04096 decorator->Remove();
04097 decorator->Destroy();
04098 }
04099 }
04100
04101
04102
04103
04104
04105
04110
04111
04112 bool nMachine::operator == ( nMachine const & other ) const
04113 {
04114 return this == &other;
04115 }
04116
04117
04118
04119
04120
04121
04126
04127
04128 bool nMachine::operator !=( nMachine const & other ) const
04129 {
04130 return this != &other;
04131 }
04132
04133
04134 class nMachinePTR
04135 {
04136 public:
04137 mutable nMachine * machine;
04138 nMachinePTR(): machine(tNEW(nMachine)()){};
04139 ~nMachinePTR(){tDESTROY(machine);}
04140 nMachinePTR(nMachinePTR const & other): machine(other.machine){other.machine=0;}
04141 nMachinePTR & operator=(nMachinePTR const & other){ machine = other.machine; other.machine=0;return *this;}
04142 };
04143
04144 typedef std::map< tString, nMachinePTR > nMachineMap;
04145 static nMachineMap & sn_GetMachineMap()
04146 {
04147 static nMachineMap map;
04148 return map;
04149 }
04150
04151 static nMachine & sn_LookupMachine( tString const & address )
04152 {
04153
04154 nMachineMap & map = sn_GetMachineMap();
04155 return map[ address ].machine->SetIP( address );
04156 }
04157
04158
04159
04160
04161
04162
04167
04168
04169 nMachine & nMachine::GetMachine( unsigned short userID )
04170 {
04171
04172 Expire();
04173
04174
04175 if ( userID == 0 && sn_GetNetState() != nCLIENT )
04176 {
04177 static nMachine server;
04178 return server;
04179 }
04180
04181 tASSERT( userID <= MAXCLIENTS+1 );
04182
04183 if( sn_GetNetState() != nSERVER )
04184 {
04185
04186 static nMachine invalid;
04187 return invalid;
04188 }
04189
04190
04191 tVERIFY( userID <= MAXCLIENTS+1 );
04192 if( !sn_Connections[userID].socket )
04193 {
04194
04195 static nMachine invalid;
04196 return invalid;
04197 }
04198 tString address;
04199 peers[ userID ].GetAddress( address );
04200
04201 #ifdef DEBUG_X
04202
04203 tString newIP;
04204 newIP << address << " " << userID;
04205 address = newIP;
04206 #endif
04207
04208
04209 return sn_LookupMachine( address );
04210 }
04211
04212
04213 static void sn_Erase( nMachineMap & map, nMachineMap::iterator & iter )
04214 {
04215 if ( iter != map.end() )
04216 {
04217 map.erase( iter );
04218 iter = map.end();
04219 }
04220 }
04221
04222
04223
04224
04225
04226
04229
04230
04231 void nMachine::Expire( void )
04232 {
04233 static double lastTime = tSysTimeFloat();
04234 double time = tSysTimeFloat();
04235 REAL dt = time - lastTime;
04236 if (dt <= 60)
04237 return;
04238 lastTime = time;
04239
04240
04241 nMachineMap & map = sn_GetMachineMap();
04242 nMachineMap::iterator toErase = map.end();
04243 for( nMachineMap::iterator iter = map.begin(); iter != map.end(); ++iter )
04244 {
04245
04246 sn_Erase( map, toErase );
04247
04248 nMachine & machine = *(*iter).second.machine;
04249
04250
04251 if ( time > machine.banned_ && ( machine.lastUsed_ > time - 300 || machine.players_ > 0 ) )
04252 {
04253 machine.kph_.Add( 0, dt / 3600 );
04254 machine.kph_.Timestep( dt / 3600*24 );
04255 }
04256
04257
04258 if ( machine.players_ == 0 && machine.lastUsed_ < time - 300.0 && machine.banned_ < time && machine.kph_.GetAverage() < 0.5 )
04259 toErase = iter;
04260
04261 }
04262
04263
04264 sn_Erase( map, toErase );
04265 }
04266
04267
04268 static REAL sn_spectatorTime = 0;
04269 static tSettingItem< REAL > sn_spectatorTimeConf( "NETWORK_SPECTATOR_TIME", sn_spectatorTime );
04270
04271
04272
04273
04274
04275
04278
04279
04280 void nMachine::KickSpectators( void )
04281 {
04282 double time = tSysTimeFloat();
04283
04284
04285 if ( sn_GetNetState() == nSERVER && sn_spectatorTime > 0 )
04286 {
04287 for ( int i = MAXCLIENTS; i >= 1; --i )
04288 {
04289 if ( sn_Connections[i].socket )
04290 {
04291 nMachine & machine = GetMachine( i );
04292 if ( machine.players_ == 0 && machine.lastPlayerAction_ + sn_spectatorTime < time )
04293 {
04294 sn_KickUser( i, tOutput("$network_kill_spectator"), 0 );
04295 }
04296 }
04297 }
04298 }
04299 }
04300
04301
04302 static REAL sn_autobanOffset = 5;
04303 static REAL sn_autobanFactor = 10;
04304 static REAL sn_autobanMaxKPH = 30;
04305
04306 static tSettingItem< REAL > sn_autobanOffsetSetting( "NETWORK_AUTOBAN_OFFSET", sn_autobanOffset );
04307 static tSettingItem< REAL > sn_autobanFactorSetting( "NETWORK_AUTOBAN_FACTOR", sn_autobanFactor );
04308 static tSettingItem< REAL > sn_autobanMaxKPHSetting( "NETWORK_AUTOBAN_MAX_KPH", sn_autobanMaxKPH );
04309
04310
04311
04312
04313
04314
04318
04319
04320 void nMachine::OnKick( REAL severity )
04321 {
04322
04323 if ( banned_ > tSysTimeFloat() )
04324 return;
04325
04326
04327 REAL kph = kph_.GetAverage() - sn_autobanOffset;
04328 if ( kph > 0 )
04329 {
04330
04331 REAL banTime = 60 * kph * sn_autobanFactor;
04332 Ban( banTime, tString(tOutput( "$network_ban_kick" )) );
04333 }
04334
04335
04336 if ( sn_autobanMaxKPH > 0 )
04337 kph_.Add( severity * sn_autobanMaxKPH, 2/sn_autobanMaxKPH );
04338
04339 con << tOutput( "$network_ban_kph", GetIP(), GetKicksPerHour() );
04340 }
04341
04342 static bool sn_printBans = true;
04343
04344
04345
04346
04347
04348
04352
04353
04354 void nMachine::Ban( REAL time )
04355 {
04356 lastUsed_ = tSysTimeFloat();
04357
04358
04359 banned_ = tSysTimeFloat() + time;
04360
04361 if ( sn_printBans )
04362 {
04363 if ( time > 0 )
04364 con << tOutput( "$network_ban", GetIP(), int(time/60), banReason_.Len() > 1 ? banReason_ : tOutput( "$network_ban_noreason" ) );
04365 else
04366 con << tOutput( "$network_noban", GetIP() );
04367 }
04368 }
04369
04370
04371
04372
04373
04374
04379
04380
04381 void nMachine::Ban( REAL time, tString const & reason )
04382 {
04383 banReason_ = tString();
04384 if ( reason.Len() > 2 )
04385 banReason_ = reason;
04386
04387 Ban( time );
04388 }
04389
04390
04391
04392
04393
04394
04398
04399
04400 REAL nMachine::IsBanned( void ) const
04401 {
04402
04403 double time = tSysTimeFloat();
04404 if ( time > banned_ )
04405 return 0;
04406
04407 return banned_ - time;
04408 }
04409
04410
04411
04412
04413
04414
04417
04418
04419 void nMachine::AddPlayer( void )
04420 {
04421 lastPlayerAction_ = lastUsed_ = tSysTimeFloat();
04422
04423 players_++;
04424 }
04425
04426
04427
04428
04429
04430
04433
04434
04435 void nMachine::RemovePlayer( void )
04436 {
04437 lastPlayerAction_ = lastUsed_ = tSysTimeFloat();
04438
04439 players_--;
04440 if ( players_ < 0 )
04441 players_ = 0;
04442 }
04443
04444
04445
04446
04447
04448
04452
04453
04454 int nMachine::GetPlayerCount( void )
04455 {
04456 return players_;
04457 }
04458
04459
04460 static char const * sn_machinesFileName = "bans.txt";
04461
04462 class nMachinePersistor
04463 {
04464 public:
04465
04466 static void SaveMachines()
04467 {
04468 std::ofstream s;
04469 if (tDirectories::Var().Open( s, sn_machinesFileName ) )
04470 {
04471 nMachineMap & map = sn_GetMachineMap();
04472 for( nMachineMap::iterator iter = map.begin(); iter != map.end(); ++iter )
04473 {
04474 nMachine & machine = *(*iter).second.machine;
04475
04476 {
04477 s << (*iter).first << " " << machine.IsBanned() << " " << machine.kph_ << " " << machine.GetBanReason() << "\n";
04478 }
04479 }
04480 }
04481 }
04482
04483
04484 static void LoadMachines()
04485 {
04486 sn_printBans = false;
04487
04488 tTextFileRecorder machines( tDirectories::Var(), sn_machinesFileName );
04489 while ( !machines.EndOfFile() )
04490 {
04491 std::stringstream line( machines.GetLine() );
04492
04493
04494 tString address;
04495 REAL banTime;
04496
04497
04498 line >> address >> banTime;
04499 std::ws(line);
04500
04501
04502 nAverager kph;
04503 char c;
04504 line.get(c);
04505 line.putback(c);
04506 if ( c == '(' )
04507 {
04508 line >> kph;
04509 std::ws(line);
04510 }
04511
04512
04513 tString reason;
04514 reason.ReadLine( line );
04515
04516 if ( address.Len() > 2 )
04517 {
04518
04519 nMachine & machine = sn_LookupMachine( address );
04520 machine.Ban( banTime, reason );
04521 machine.kph_ = kph;
04522 }
04523 }
04524
04525 sn_printBans = true;
04526 }
04527 }
04528 ;
04529
04530 static void sn_SaveMachines()
04531 {
04532 nMachinePersistor::SaveMachines();
04533 }
04534
04535
04536 static void sn_LoadMachines()
04537 {
04538 nMachinePersistor::LoadMachines();
04539 }
04540
04541
04542
04543
04544
04545
04549
04550
04551 REAL nMachine::GetKicksPerHour( void ) const
04552 {
04553 return this->kph_.GetAverage();
04554 }
04555
04556
04557
04558
04559
04560
04565
04566
04567 nMachine const & nMachine::GetKicksPerHour( REAL & kph ) const
04568 {
04569 kph = this->kph_.GetAverage();
04570 return *this;
04571 }
04572
04573
04574
04575
04576
04577
04581
04582
04583 tString const & nMachine::GetIP( void ) const
04584 {
04585 return this->IP_;
04586 }
04587
04588
04589
04590
04591
04592
04597
04598
04599 nMachine const & nMachine::GetIP( tString & IP ) const
04600 {
04601 IP = this->IP_;
04602 return *this;
04603 }
04604
04605
04606
04607
04608
04609
04614
04615
04616 nMachine & nMachine::SetIP( tString const & IP )
04617 {
04618 lastUsed_ = tSysTimeFloat();
04619
04620 this->IP_ = IP;
04621 return *this;
04622 }
04623
04624
04625
04626
04627
04628
04632
04633
04634 tString const & nMachine::GetBanReason( void ) const
04635 {
04636 return this->banReason_;
04637 }
04638
04639
04640
04641
04642
04643
04648
04649
04650 nMachine const & nMachine::GetBanReason( tString & reason ) const
04651 {
04652 reason = this->banReason_;
04653 return *this;
04654 }
04655
04656
04657
04658
04659
04660
04661
04662
04663 static void sn_UnBanConf(std::istream &s)
04664 {
04665 if ( !s.good() || s.eof() )
04666 {
04667 con << "Usage: UNBAN_IP <ip>\n";
04668 return;
04669 }
04670
04671
04672 tString address;
04673 s >> address;
04674
04675 if ( address.Len() < 8 )
04676 {
04677 con << "Usage: UNBAN_IP <ip>, no or too short ip given.\n";
04678 }
04679
04680 else
04681 {
04682 sn_LookupMachine( address ).Ban( 0 );
04683 }
04684 }
04685
04686 static tConfItemFunc sn_unBanConf("UNBAN_IP",&sn_UnBanConf);
04687
04688
04689 static void sn_BanConf(std::istream &s)
04690 {
04691
04692 tString address;
04693 s >> address;
04694
04695 if ( !s.good() && address.Len() < 7 )
04696 {
04697 con << "Usage: BAN_IP <ip> <time in minutes (defaults to 60)> <reason>\n";
04698 return;
04699 }
04700
04701 REAL duration = 60;
04702 s >> duration;
04703
04704
04705 tString reason;
04706 std::ws(s);
04707 if ( s.good() )
04708 {
04709 reason.ReadLine(s);
04710 }
04711
04712
04713 if ( address.Len() > 4 )
04714 {
04715 sn_LookupMachine( address ).Ban( duration * 60, reason );
04716 }
04717 }
04718
04719 static tConfItemFunc sn_banConf("BAN_IP",&sn_BanConf);
04720
04721
04722 static void sn_ListBanConf(std::istream &s)
04723 {
04724 nMachineMap & map = sn_GetMachineMap();
04725 for( nMachineMap::iterator iter = map.begin(); iter != map.end(); ++iter )
04726 {
04727 nMachine & machine = *(*iter).second.machine;
04728 REAL banned = machine.IsBanned();
04729 if ( banned > 0 )
04730 {
04731 con << tOutput( "$network_ban", machine.GetIP(), int(banned/60), machine.GetBanReason() );
04732 }
04733 }
04734 }
04735
04736 static tConfItemFunc sn_listBanConf("BAN_LIST",&sn_ListBanConf);
04737
04738
04739
04740
04741
04742
04745
04746
04747 void nMachineDecorator::OnDestroy( void )
04748 {
04749 }
04750
04751
04752
04753
04754
04755
04758
04759
04760 nMachineDecorator::nMachineDecorator( void )
04761 {
04762 }
04763
04764
04765
04766
04767
04768
04771
04772
04773 nMachineDecorator::~nMachineDecorator( void )
04774 {
04775 Remove();
04776 }
04777
04778
04779
04780
04781
04782
04786
04787
04788 nMachineDecorator::nMachineDecorator( nMachine & machine )
04789 {
04790 Insert( machine.decorators_ );
04791 }
04792