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
00029 #include "tMemManager.h"
00030 #include "nNetObject.h"
00031 #include "tLocale.h"
00032
00033 #include "nSimulatePing.h"
00034 #include "tSysTime.h"
00035 #include "tToDo.h"
00036 #include "nObserver.h"
00037 #include "nConfig.h"
00038 #include "tRecorder.h"
00039
00040 #include <deque>
00041 #include <set>
00042 #include <map>
00043
00044
00045 #ifdef DEBUG
00046 int sn_WatchNetID = 0;
00047 extern nMessage* sn_WatchMessage;
00048 #endif
00049
00050 tDEFINE_REFOBJ( nNetObject )
00051
00052
00053 int sn_pingCharityServer=0;
00054
00055
00056
00057
00058
00059 static unsigned short net_current_id=1;
00060
00061
00062
00063 static const unsigned short net_max_current_id_max = 32000;
00064
00065
00066
00067
00068 static const unsigned short net_max_current_id_min = 16000;
00069
00070
00071
00072 static unsigned short net_max_current_id = net_max_current_id_min;
00073
00074 #ifdef DEBUG
00075 static void sn_BreakOnObjectID( unsigned int id )
00076 {
00077 #ifdef DEBUG_X
00078 static unsigned int breakOnID = sn_WatchNetID;
00079 static REAL minTime = 0;
00080 if ( id == breakOnID && tSysTimeFloat() > minTime )
00081 st_Breakpoint();
00082 #endif
00083 }
00084
00085 static void sn_BreakOnObject( nNetObject * object )
00086 {
00087 if ( object )
00088 sn_BreakOnObjectID( object->ID() );
00089 }
00090 #endif
00091
00092 static unsigned short inc_id(){
00093 unsigned short ret=net_current_id++;
00094
00095 if ( net_current_id > net_max_current_id )
00096 {
00097 net_current_id = 1;
00098 }
00099
00100 if (net_current_id==0)
00101 net_current_id++;
00102 return ret;
00103 }
00104
00105 #define ID_PREFETCH 50
00106
00107
00108 unsigned short net_reserved_id[ID_PREFETCH];
00109 unsigned short distribute=0,request=0;
00110
00111
00112
00113 tArray<unsigned short> sn_netObjectsOwner;
00114
00115
00116
00117 static std::deque<nNetObjectID> sn_freedIDs;
00118
00119
00120 static tArray<bool> sn_netObjects_AcceptClientSync;
00121
00122
00123 tArray<tJUST_CONTROLLED_PTR<nNetObject> > sn_netObjects(1024);
00124
00125 static const REAL nDeletedTimeout = 60.0f;
00126
00127 struct nDeletedInfo
00128 {
00129 tJUST_CONTROLLED_PTR<nNetObject> object_;
00130 nTimeAbsolute time_;
00131
00132 nDeletedInfo()
00133 {
00134 this->UnSet();
00135 }
00136
00137 void Set( nNetObject* object )
00138 {
00139 #ifdef DEBUG
00140 sn_BreakOnObject( object );
00141 #endif
00142 time_ = tSysTimeFloat();
00143 object_ = object;
00144 }
00145
00146 void UnSet( )
00147 {
00148 time_ = - nDeletedTimeout * 2.0f;
00149 object_ = NULL;
00150 }
00151 };
00152
00153
00154 typedef std::map< nNetObjectID, nDeletedInfo > nDeletedInfos;
00155 static nDeletedInfos sn_netObjectsDeleted;
00156
00157 static bool free_server( nNetObjectID id )
00158 {
00159 if ( bool(sn_netObjectsOwner[id]) || bool(sn_netObjects[id]) )
00160 {
00161 return false;
00162 }
00163
00164 nDeletedInfos::iterator found = sn_netObjectsDeleted.find( id );
00165 if ( found != sn_netObjectsDeleted.end() )
00166 {
00167 nDeletedInfo & deleted = (*found).second;
00168 if ( deleted.time_ > tSysTimeFloat() - nDeletedTimeout )
00169 {
00170 return false;
00171 }
00172
00173 if ( deleted.object_ )
00174 {
00175 #ifdef DEBUG
00176 sn_BreakOnObjectID( id );
00177 #endif
00178
00179 deleted.UnSet();
00180 return false;
00181 }
00182 }
00183
00184 return true;
00185 }
00186
00187 static unsigned short next_free_server_nokill(){
00188
00189 if ( net_max_current_id > net_max_current_id_min )
00190 {
00191 net_max_current_id--;
00192 if ( net_current_id > net_max_current_id )
00193 net_current_id = 1;
00194 }
00195
00196
00197 while ( sn_freedIDs.size() > 1000 && sn_freedIDs.size() * 20 > net_max_current_id )
00198 {
00199 nNetObjectID freedID = sn_freedIDs.front();
00200 sn_freedIDs.pop_front();
00201 #ifdef DEBUG
00202 sn_BreakOnObjectID( freedID );
00203 #endif
00204 sn_netObjectsOwner[freedID] = 0;
00205 }
00206
00207 nNetObjectID start_id = net_current_id;
00208 if (sn_GetNetState()==nSERVER || sn_GetNetState()==nSTANDALONE)
00209 {
00210 do
00211 {
00212 inc_id();
00213 }
00214 while ( !free_server( net_current_id ) && net_current_id != start_id );
00215
00216 if ( net_current_id != start_id )
00217 {
00218
00219 #ifdef DEBUG
00220 sn_BreakOnObjectID( net_current_id );
00221 #endif
00222 return net_current_id;
00223 }
00224 else
00225 {
00226
00227 return 0;
00228 }
00229 }
00230
00231 else
00232 {
00233 tERR_ERROR("next_free_server is not available for clients.");
00234 return 0;
00235 }
00236 }
00237
00238
00239 static int kill_id_hog()
00240 {
00241 int i;
00242 int grabbedIDs[MAXCLIENTS+2];
00243 int usedIDs[MAXCLIENTS+2];
00244
00245 for ( i = MAXCLIENTS+1; i>=0; --i )
00246 {
00247 grabbedIDs[i] = 0;
00248 usedIDs[i] = 0;
00249 }
00250
00251
00252 for ( i = sn_netObjectsOwner.Len()-1; i>=0; --i )
00253 {
00254 int owner = sn_netObjectsOwner( i );
00255 if ( owner >= 0 && owner <= MAXCLIENTS )
00256 {
00257 if ( sn_netObjects[i] )
00258 {
00259 usedIDs[ owner ] ++;
00260 }
00261 else if ( owner > 0 )
00262 {
00263 grabbedIDs[ owner ] ++;
00264 }
00265 }
00266 }
00267
00268
00269 int maxGrabbed = 2 * ID_PREFETCH + 1;
00270 int maxUsed = 0;
00271 int maxGrabbedUser = -1;
00272 int maxUsedUser = -1;
00273
00274 for ( i = MAXCLIENTS+1; i > 0; --i )
00275 {
00276 if ( grabbedIDs[i] > maxGrabbed )
00277 {
00278 maxGrabbedUser = i;
00279 maxGrabbed = grabbedIDs[i];
00280 }
00281
00282 if ( usedIDs[i] > maxUsed )
00283 {
00284 maxUsedUser = i;
00285 maxUsed = usedIDs[i];
00286 }
00287 }
00288
00289
00290 if ( maxGrabbedUser > 0 )
00291 {
00292 con << "Killing top ID grabber.\n";
00293 st_Breakpoint();
00294 sn_DisconnectUser( maxGrabbedUser, "$network_kill_maxidgrabber" );
00295 return maxGrabbedUser;
00296 }
00297
00298
00299 else if ( maxUsedUser > 0 )
00300 {
00301 con << "Killing top ID user.\n";
00302 st_Breakpoint();
00303 sn_DisconnectUser( maxUsedUser, "$network_kill_maxiduser" );
00304 return maxUsedUser;
00305 }
00306
00307 return -1;
00308 }
00309
00310
00311 static bool sg_todoKillHog=false;
00312 static void kill_id_hog_todo()
00313 {
00314 if ( sg_todoKillHog )
00315 kill_id_hog();
00316 sg_todoKillHog=false;
00317 }
00318
00319 static unsigned short next_free_server( bool kill ){
00320 nNetObjectID id = next_free_server_nokill();
00321 if ( id > 0 )
00322 {
00323 return id;
00324 }
00325 else
00326 {
00327
00328 sg_todoKillHog=true;
00329 st_ToDo( kill_id_hog_todo );
00330
00331
00332 int increase = 1000;
00333 if ( net_max_current_id + 2 * increase < net_max_current_id_max )
00334 net_max_current_id += increase;
00335 else
00336 net_max_current_id = net_max_current_id + ( net_max_current_id_max - net_max_current_id );
00337
00338 id = next_free_server_nokill();
00339 if ( id > 0 )
00340 {
00341 return id;
00342 }
00343 else
00344 {
00345
00346 if ( kill )
00347 throw nKillHim();
00348
00349
00350 con << "Emergency exit: desperately ran out of IDs.\n";
00351 exit(-1);
00352 }
00353 }
00354 }
00355
00356 void req_id_handler(nMessage &m){
00357 unsigned short stop = distribute;
00358 if (distribute == 0)
00359 stop = ID_PREFETCH;
00360
00361 if (sn_GetNetState()==nSERVER)
00362 Cheater(m.SenderID());
00363 else{
00364 while (!m.End())
00365 {
00366 unsigned short id, count=1;
00367 m.Read(id);
00368 if (!m.End())
00369 m.Read(count);
00370
00371 for (unsigned short i=id + count - 1; i>= id && request+1 != stop; i--)
00372 {
00373 if (sn_netObjects[i])
00374 {
00375 con << "Warning! Network id receive error on ID " << i << " belonging to client " << sn_netObjects[i]->Owner() << "\n";
00376 con << "while recieving ID block " << id << "-" << id+count-1 << " from netmessage " << m.MessageID() << ".\n";
00377
00378 }
00379 else
00380 {
00381 net_reserved_id[request] = i;
00382 #ifdef DEBUG
00383
00384 #endif
00385 request++;
00386 if (request>=ID_PREFETCH)
00387 request=0;
00388 }
00389 }
00390 }
00391 }
00392 }
00393
00394 nDescriptor req_id(20,req_id_handler,"req_id");
00395
00396 void id_req_handler(nMessage &m){
00397
00398
00399 if (sn_GetNetState()==nSERVER && m.SenderID()<=MAXCLIENTS)
00400 {
00401 if (m.End())
00402 {
00403 tJUST_CONTROLLED_PTR< nMessage > rep=new nMessage(req_id);
00404 unsigned short id=next_free_server(true);
00405 sn_netObjectsOwner[id]=m.SenderID();
00406
00407 rep->Write(id);
00408 rep->Send(m.SenderID());
00409
00410 #ifdef DEBUG
00411
00412 #endif
00413 }
00414 else
00415 {
00416
00417 unsigned short num;
00418 m.Read(num);
00419
00420
00421 if ( num > ID_PREFETCH*4 )
00422 {
00423 throw nKillHim();
00424 }
00425
00426 tJUST_CONTROLLED_PTR< nMessage > rep=new nMessage(req_id);
00427
00428 unsigned short begin_block=0;
00429 unsigned short block_len=0;
00430
00431 for (int i = num-1; i>=0; i--)
00432 {
00433 nNetObjectID id = next_free_server(true);
00434
00435 sn_netObjectsOwner[id]=m.SenderID();
00436
00437 if (begin_block + block_len == id)
00438 block_len++;
00439 else
00440 {
00441 if (block_len > 0)
00442 {
00443
00444 rep->Write(begin_block);
00445 rep->Write(block_len);
00446 }
00447 begin_block = id;
00448 block_len = 1;
00449 }
00450 }
00451 if (block_len > 0)
00452 {
00453
00454 rep->Write(begin_block);
00455 rep->Write(block_len);
00456 }
00457
00458 rep->Send(m.SenderID());
00459 }
00460 }
00461 }
00462
00463 nDescriptor id_req(21,id_req_handler,"id_req_handler");
00464
00465 unsigned short next_free(){
00466 unsigned short ret=0;
00467
00468 do{
00469 if (sn_GetNetState()==nCLIENT){
00470 unsigned short need_soon = request + ID_PREFETCH - distribute;
00471 if (need_soon > ID_PREFETCH)
00472 need_soon -= ID_PREFETCH;
00473 if (need_soon < (ID_PREFETCH >> 1))
00474 {
00475 tJUST_CONTROLLED_PTR< nMessage > m = new nMessage(id_req);
00476 m->Write(ID_PREFETCH >> 2);
00477 m->Send(0);
00478 }
00479
00480 double timeout=tSysTimeFloat()+60;
00481 while (sn_Connections[0].socket && distribute==request && tSysTimeFloat()<timeout){
00482
00483 #ifdef DEBUG
00484
00485 #endif
00486 sn_Receive();
00487 nNetObject::SyncAll();
00488 sn_SendPlanned();
00489
00490 tAdvanceFrame(1000000);
00491 }
00492 if (tSysTimeFloat()>=timeout)
00493 tERR_ERROR_INT("Not enough nNetObject IDs to distribute. Sorry!\n");
00494
00495 ret=net_reserved_id[distribute];
00496
00497 distribute++;
00498 if (distribute>=ID_PREFETCH)
00499 distribute=0;
00500
00501 net_current_id=ret+1;
00502 }
00503 else
00504 {
00505 ret=next_free_server(false);
00506 }
00507
00508 if (sn_netObjects[ret]){
00509 con << "Warning! Network id assignment error on ID " << ret << " belonging to client " << sn_netObjects[ret]->Owner() << "\n";
00510 ret=0;
00511 }
00512
00513 }while (ret==0 && sn_Connections[0].socket);
00514
00515 return ret;
00516 }
00517
00518 void first_fill_ids(){
00519 if (sn_GetNetState()!=nCLIENT)
00520 tERR_ERROR("first_fill_ids is only for clients!");
00521
00522 distribute=request=0;
00523
00524 tJUST_CONTROLLED_PTR< nMessage > m = new nMessage(id_req);
00525 m->Write(ID_PREFETCH - 10);
00526 m->Send(0);
00527 }
00528
00529
00530 void Cheater(int i)
00531 {
00532
00533 if (i != 0 && !sn_Connections[i].socket)
00534 {
00535 return;
00536 }
00537
00538 con << "User " << i << " tried to cheat.\n";
00539
00540
00541 if ( i == 0 )
00542
00543 throw tGenericException("There was a network error, the connection to the server had to be terminated.", "Network Error");
00544 else
00545 sn_DisconnectUser(i, "$network_kill_cheater" );
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555 void nNetObject::AddRef(){
00556 tASSERT ( this );
00557
00558 if ( this )
00559 {
00560 tASSERT( refCtr_ >= 0 );
00561 refCtr_++;
00562 tASSERT( refCtr_ >= 0 );
00563 }
00564 }
00565
00566 void nNetObject::ReleaseOwnership(){
00567 if ( this->createdLocally )
00568 {
00569 this->createdLocally = false;
00570 Release();
00571 }
00572 }
00573
00574 void nNetObject::TakeOwnership(){
00575 if ( !this->createdLocally )
00576 {
00577 this->createdLocally = true;
00578
00579 }
00580 }
00581
00582 void nNetObject::Release(){
00583 tASSERT( this );
00584
00585 if (this){
00586 if (refCtr_>0)
00587 refCtr_--;
00588 else
00589 {
00590 #ifdef DEBUG
00591 tERR_ERROR("Negative recfcount!");
00592 #else
00593 return;
00594 #endif
00595 }
00596 int extra=0;
00597
00598
00599
00600
00601 if (id > 0 && static_cast<nNetObject*>(sn_netObjects[id])==this)
00602 {
00603 if ( createdLocally )
00604 extra = -1;
00605 }
00606
00607
00608
00609 if ( refCtr_ + extra <= 0 )
00610 {
00611 refCtr_ = -100;
00612 delete this;
00613 }
00614 }
00615 }
00616
00617
00618 int nNetObject::GetRefcount() const
00619 {
00620 int extra=0;
00621
00622
00623
00624
00625 if (id > 0 && static_cast<nNetObject*>(sn_netObjects[id])==this)
00626 {
00627 if ( createdLocally )
00628 extra = -1;
00629 }
00630
00631
00632
00633 return this->refCtr_ + extra;
00634 }
00635
00636 nObserver& nNetObject::GetObserver() const
00637 {
00638 if ( !this->observer_ )
00639 {
00640 this->observer_ = tNEW( nObserver );
00641 this->observer_->SetObject( this );
00642 }
00643
00644 return *this->observer_;
00645 }
00646
00647
00648
00649 void nNetObject::Dump( tConsole& con )
00650 {
00651 tString str;
00652 this->PrintName( str );
00653 con << str;
00654 }
00655
00656
00657 bool sn_Update(unsigned short &old,unsigned short n){
00658 if ( 0 == old )
00659 {
00660 old = n;
00661 return true;
00662 }
00663
00664 short diff=old-n;
00665 if (diff<0){
00666 old=n;
00667 return true;
00668 }
00669 else
00670 return false;
00671 }
00672
00673
00674 bool sn_Update(unsigned long &old,unsigned long n){
00675 if ( 0 == old )
00676 {
00677 old = n;
00678 return true;
00679 }
00680
00681 long diff=old-n;
00682 if (diff<0){
00683 old=n;
00684 return true;
00685 }
00686 else
00687 return false;
00688 }
00689
00690
00691
00692 bool nNetObject::SyncIsNew(nMessage &m){
00693 unsigned long int bigID = m.MessageIDBig();
00694
00695 return sn_Update(lastSyncID_,bigID);
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707 nNetObject::nNetObject(int own):lastSyncID_(0),
00708 id(0),refCtr_(0),owner(own){
00709 #ifdef DEBUG
00710
00711
00712
00713 #endif
00714 syncListID_ = -1;
00715
00716 createdLocally = true;
00717
00718 if (own<0) owner=::sn_myNetID;
00719 }
00720
00721 static nNetObjectRegistrar* sn_Registrar = NULL;
00722
00723 nNetObjectRegistrar::nNetObjectRegistrar()
00724 {
00725 sender = 100;
00726 id = 0;
00727 oldRegistrar = sn_Registrar;
00728 sn_Registrar = this;
00729 }
00730
00731 nNetObjectRegistrar::~nNetObjectRegistrar()
00732 {
00733 tASSERT( sn_Registrar == this );
00734 sn_Registrar = oldRegistrar;
00735 }
00736
00737
00738 void nNetObject::Register( const nNetObjectRegistrar& registrar )
00739 {
00740 tASSERT( this == registrar.object );
00741 tASSERT( id == 0 || id == registrar.id );
00742
00743 if ( this->id == registrar.id )
00744 {
00745 return;
00746 }
00747
00748 id = registrar.id;
00749
00750 if (sn_netObjectsOwner[id]!= registrar.sender || sn_netObjects[id]){
00751 #ifdef DEBUG
00752 con << "Netobject " << id << " is already reserved!\n";
00753 #endif
00754 if (sn_netObjectsOwner[id]!=registrar.sender){
00755 Cheater( registrar.sender );
00756 nReadError();
00757 }
00758 }
00759 else
00760 {
00761 #ifdef DEBUG
00762 sn_BreakOnObjectID( id );
00763 #endif
00764 sn_netObjects[id]=this;
00765 }
00766
00767 if (sn_GetNetState()!=nCLIENT)
00768 owner=registrar.sender;
00769
00770
00771 sn_netObjectsOwner[id]=owner;
00772 sn_netObjects_AcceptClientSync[id]=false;
00773 }
00774
00775 nNetObject::nNetObject(nMessage &m):lastSyncID_(m.MessageIDBig()),refCtr_(0){
00776
00777
00778 id = 0;
00779 owner = 0;
00780
00781 syncListID_ = -1;
00782
00783 tASSERT( sn_Registrar );
00784 nNetObjectRegistrar& registrar = *sn_Registrar;
00785
00786 createdLocally = false;
00787
00788 m.Read( registrar.id );
00789 #ifdef DEBUG
00790
00791
00792
00793 #endif
00794 m.Read( owner );
00795
00796
00797 if ( sn_GetNetState() == nSERVER )
00798 {
00799 if ( owner != m.SenderID() )
00800 {
00801 throw nKillHim();
00802 }
00803 }
00804
00805 registrar.object = this;
00806 registrar.sender = m.SenderID();
00807
00808 knowsAbout[m.SenderID()].knowsAboutExistence=true;
00809 #ifdef DEBUG
00810
00811 #endif
00812 }
00813
00814 void nNetObject::DoBroadcastExistence(){
00815 if (BroadcastExistence() &&
00816 ( sn_GetNetState()!=nCLIENT ||
00817 ( owner == ::sn_myNetID && AcceptClientSync() )
00818 )
00819 )
00820 {
00821 int maxUser = (sn_GetNetState() == nSERVER) ? MAXCLIENTS : 0;
00822 int minUser = (sn_GetNetState() == nSERVER) ? 1 : 0;
00823 for (int user = maxUser; user >= minUser; --user)
00824 {
00825
00826 if ( !knowsAbout[user].knowsAboutExistence && sn_Connections[user].socket )
00827 RequestSync( user, true );
00828 }
00829 }
00830 }
00831
00832
00833 struct nDestroyInfo
00834 {
00835 unsigned short id;
00836 unsigned short sender;
00837 bool actionOnDeleteExecuted;
00838 nTimeAbsolute timeout;
00839 };
00840
00841 static tArray< nDestroyInfo > sn_Destroyed;
00842 static std::set< unsigned short > sn_LocallyDestroyedIDs;
00843
00844
00845 bool sn_WasDeletedLocally( unsigned short id )
00846 {
00847
00848 std::set< unsigned short >::iterator found = sn_LocallyDestroyedIDs.find(id);
00849 if ( found != sn_LocallyDestroyedIDs.end() )
00850 {
00851
00852 sn_LocallyDestroyedIDs.erase( found );
00853 return true;
00854 }
00855
00856 return false;
00857 }
00858
00859 void nNetObject::InitAfterCreation(){
00860 DoBroadcastExistence();
00861
00862
00863 #ifdef DEBUG
00864 sn_BreakOnObjectID( id );
00865 #endif
00866
00867
00868 sn_WasDeletedLocally( id );
00869 }
00870
00871
00872 static void net_destroy_handler(nMessage &m){
00873
00874 unsigned short id;
00875
00876 while (!m.End()){
00877 m.Read(id);
00878 #ifdef DEBUG
00879 sn_BreakOnObjectID( id );
00880 #endif
00881
00882 if (sn_WasDeletedLocally( id ))
00883 continue;
00884
00885 nDestroyInfo& info = sn_Destroyed[ sn_Destroyed.Len() ];
00886 info.id = id;
00887 info.sender = m.SenderID();
00888 info.actionOnDeleteExecuted=false;
00889 info.timeout=tSysTimeFloat()+nDeletedTimeout;
00890
00891
00892 if (nNetObject *no=sn_netObjects[id])
00893 {
00894 tASSERT( !no->Owned() );
00895
00896 no->ActionOnDelete();
00897 info.actionOnDeleteExecuted=true;
00898
00899
00900
00901 if ( no->Owned() )
00902 sn_Destroyed.SetLen( sn_Destroyed.Len() - 1 );
00903 }
00904
00905 #ifdef DEBUG
00906
00907
00908
00909 #endif
00910
00911 }
00912
00913 }
00914
00915 static void sn_DoDestroy()
00916 {
00917 #ifdef DEBUG
00918 static bool recursion = false;
00919 tASSERT( !recursion );
00920 recursion = true;
00921 #endif
00922
00923 for ( int i = sn_Destroyed.Len()-1 ; i>=0; --i )
00924 {
00925 nDestroyInfo& info = sn_Destroyed( i );
00926 unsigned short id = info.id;
00927
00928
00929 bool timedOut = ( info.timeout < tSysTimeFloat() );
00930
00931
00932 nNetObject *no=sn_netObjects[id];
00933
00934
00935 if (bool(no) || timedOut){
00936 #ifdef DEBUG
00937 sn_BreakOnObjectID( id );
00938 #endif
00939
00940 if (!sn_WasDeletedLocally( id ) && !timedOut )
00941 {
00942 if (no->Owner()==info.sender || info.sender==0){
00943 sn_netObjectsDeleted [ id ].Set( no );
00944
00945 if (!info.actionOnDeleteExecuted)
00946 no->ActionOnDelete();
00947
00948 sn_netObjects(id)=NULL;
00949 sn_netObjectsOwner(id)=0;
00950 }
00951 else
00952 Cheater(info.sender);
00953 }
00954
00955
00956 int last = sn_Destroyed.Len()-1;
00957 info = sn_Destroyed( last );
00958 sn_Destroyed.SetLen( last );
00959 }
00960 }
00961 #ifdef DEBUG
00962 recursion = false;
00963 #endif
00964 }
00965
00966 static nCallbackReceivedComplete sn_ReceivedComplete( sn_DoDestroy );
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976 static nDescriptor net_destroy(22,net_destroy_handler,"net_destroy");
00977
00978 static tJUST_CONTROLLED_PTR< nMessage > destroyers[MAXCLIENTS+2];
00979 static REAL destroyersTime[MAXCLIENTS+2];
00980
00981
00982 static tList< nNetObject > sn_SyncRequestedObject;
00983
00984 nNetObject::~nNetObject(){
00985
00986 if ( syncListID_ >= 0 )
00987 sn_SyncRequestedObject.Remove( this, syncListID_ );
00988
00989
00990 if ( this->observer_ )
00991 {
00992 this->observer_->SetObject( NULL );
00993 }
00994
00995 #ifdef DEBUG
00996 int extra=0;
00997
00998
00999
01000
01001 if (id > 0 && static_cast<nNetObject*>(sn_netObjects[id])==this)
01002 {
01003 if ( createdLocally )
01004 extra = -1;
01005 }
01006
01007 if (refCtr_ + extra > 0)
01008 tERR_ERROR("Hey! There is stil someone interested in this nNetObject!\n");
01009
01010 #endif
01011
01012
01013 if (id)
01014 {
01015 #ifdef DEBUG
01016 sn_BreakOnObjectID( id );
01017 #endif
01018 if ( sn_GetNetState() == nSERVER )
01019 {
01020 sn_netObjectsOwner[id]=0xFFFF;
01021 sn_freedIDs.push_back( id );
01022 }
01023 else
01024 {
01025 sn_netObjectsOwner[id]=0;
01026 }
01027 }
01028
01029
01030 bool sendDestroyMessage = (sn_GetNetState()==nSERVER);
01031 if (!sendDestroyMessage && id && sn_netObjects_AcceptClientSync[id] && owner==sn_myNetID)
01032 {
01033
01034 sendDestroyMessage = true;
01035
01036
01037 sn_LocallyDestroyedIDs.insert(id);
01038 }
01039
01040
01041 if ( sendDestroyMessage )
01042 {
01043 int idsync=id;
01044 tRecorderSync< int >::Archive( "_NETOBJECT_DESTROYED", 3, idsync );
01045
01046
01047 for (int user=MAXCLIENTS;user>=0;user--){
01048 if (user!=sn_myNetID && knowsAbout[user].knowsAboutExistence ||
01049 knowsAbout[user].acksPending){
01050 if (destroyers[user]==NULL)
01051 {
01052 destroyers[user]=new nMessage(net_destroy);
01053 destroyersTime[user]=tSysTimeFloat();
01054 }
01055 destroyers[user]->Write(id);
01056
01057 if (destroyers[user]->DataLen()>100){
01058 destroyers[user]->Send(user);
01059 destroyers[user]=NULL;
01060 }
01061
01062 #ifdef DEBUG
01063
01064 #endif
01065 }
01066 }
01067 }
01068 refCtr_=100;
01069 if (id)
01070 {
01071 if (this == sn_netObjects[id])
01072 {
01073 #ifdef DEBUG
01074 sn_BreakOnObjectID( id );
01075 #endif
01076 sn_netObjects[id] = NULL;
01077 }
01078
01079
01080 nDeletedInfos::iterator found = sn_netObjectsDeleted.find( id );
01081 if ( found != sn_netObjectsDeleted.end() )
01082 {
01083 nDeletedInfo & deleted = (*found).second;
01084 deleted.Set( NULL );
01085 sn_netObjectsDeleted.erase(found);
01086 }
01087 }
01088
01089 refCtr_=-100;
01090 tCHECK_DEST;
01091 }
01092
01093
01094
01095 nNetObject *nNetObject::Object(int i){
01096 if (i==0)
01097 return NULL;
01098
01099
01100 nNetObject* deleted = NULL;
01101 nDeletedInfos::const_iterator found = sn_netObjectsDeleted.find( id );
01102 if ( found != sn_netObjectsDeleted.end() )
01103 {
01104 deleted = (*found).second.object_;
01105 }
01106
01107
01108 nNetObject *ret=ObjectDangerous( i );
01109 if ( ret )
01110 {
01111 return ret;
01112 }
01113
01114
01115 const REAL totalTimeout=10;
01116 const REAL printMessageTimeout=.5;
01117
01118 double newTimeout=tSysTimeFloat()+totalTimeout;
01119 static double timeout=-1;
01120 if ( tSysTimeFloat() > timeout )
01121 timeout = newTimeout;
01122
01123 bool printMessage=true;
01124 while (sn_Connections[0].socket &&
01125 NULL==(ret=sn_netObjects[i]) && timeout >tSysTimeFloat()){
01126 if (tSysTimeFloat()>timeout-(totalTimeout + printMessageTimeout))
01127 {
01128 if (printMessage)
01129 {
01130 con << "Waiting for NetObject with ID " << i << " to spawn...\n";
01131 printMessage=false;
01132 }
01133 if (sn_GetNetState()==nSERVER){
01134
01135
01136
01137 if ( deleted )
01138 {
01139 return deleted;
01140 }
01141
01142 nReadError();
01143
01144 con << "Now we need to leave the\n"
01145 << "system in an undefined state. I hope this works...\n";
01146
01147 Cheater(owner);
01148 return NULL;
01149 }
01150 }
01151 tAdvanceFrame(10000);
01152 sn_Receive();
01153 sn_SendPlanned();
01154 }
01155
01156 if (!ret)
01157 ret = deleted;
01158
01159 if (!ret)
01160 tERR_WARN("Netobject " << i << " requested, but was never spawned.");
01161
01162 return ret;
01163 }
01164
01165
01166 nNetObject *nNetObject::ObjectDangerous(int i ){
01167 if (i==0)
01168 {
01169 return NULL;
01170 }
01171 else
01172 {
01173 nNetObject* ret = sn_netObjects[i];
01174 if ( ret )
01175 {
01176 return ret;
01177 }
01178 else
01179 {
01180 nDeletedInfos::const_iterator found = sn_netObjectsDeleted.find( i );
01181 if ( found != sn_netObjectsDeleted.end() )
01182 {
01183 nDeletedInfo const & deleted = (*found).second;
01184 if ( deleted.time_ > tSysTimeFloat() - nDeletedTimeout )
01185 {
01186 return deleted.object_;
01187 }
01188 }
01189 }
01190 }
01191
01192 return NULL;
01193 }
01194
01195 void nNetObject::PrintName(tString &s) const
01196 {
01197 s << "Nameless NetObject nr. " << id;
01198 }
01199
01200 bool nNetObject::HasBeenTransmitted(int user) const{
01201 return (knowsAbout[user].knowsAboutExistence);
01202 }
01203
01204
01205
01206 bool nNetObject::ClearToTransmit(int user) const{
01207 return true;
01208 }
01209
01210 void nNetObject::WriteSync(nMessage &m, int run )
01211 {
01212 if ( run == 0 )
01213 {
01214 WriteSync( m );
01215 }
01216 }
01217
01218 void nNetObject::ReadSync(nMessage &m, int run )
01219 {
01220 if ( run == 0 )
01221 {
01222 ReadSync( m );
01223 }
01224 }
01225
01226 void nNetObject::WriteCreate(nMessage &m, int run )
01227 {
01228 if ( run == 0 )
01229 {
01230 WriteCreate( m );
01231 }
01232 }
01233
01234 void nNetObject::ReadCreate(nMessage &m, int run )
01235 {
01236
01237 tASSERT( run > 0 );
01238 }
01239
01240 void nNetObject::WriteAll( nMessage & m, bool create )
01241 {
01242 int lastLen = -1;
01243 int run = 0;
01244
01245
01246 while ( m.DataLen() > lastLen )
01247 {
01248 lastLen = m.DataLen();
01249 if ( create )
01250 {
01251 WriteCreate(m,run);
01252 }
01253
01254 WriteSync(m,run);
01255 ++run;
01256 }
01257 }
01258
01259 void nNetObject::ReadAll ( nMessage & m, bool create )
01260 {
01261 int lastRead = -1;
01262 int run = 0;
01263
01264
01265 while ( m.ReadSoFar() > lastRead )
01266 {
01267 lastRead = m.ReadSoFar();
01268 if ( create && run > 0 )
01269 {
01270 ReadCreate(m,run);
01271 }
01272
01273 ReadSync(m,run);
01274 ++run;
01275 }
01276 }
01277
01278 void nNetObject::WriteSync(nMessage &m){
01279 #ifdef DEBUG
01280 if (sn_GetNetState()!=nSERVER && !AcceptClientSync())
01281 tERR_ERROR("WriteSync should only be called server-side!");
01282 #endif
01283 }
01284
01285
01286
01287 void nNetObject::ReadSync(nMessage &m){
01288 if (sn_GetNetState()==nSERVER){
01289 bool back=knowsAbout[m.SenderID()].syncReq;
01290 RequestSync();
01291 knowsAbout[m.SenderID()].syncReq=back;
01292
01293
01294 }
01295 }
01296
01297 extern bool deb_net;
01298
01299
01300 void nNetObject::WriteCreate(nMessage &m){
01301 m.Write(id);
01302 m.Write(owner);
01303
01304
01305 sn_netObjects_AcceptClientSync[id]=this->AcceptClientSync();
01306
01307 if (deb_net)
01308 con << "Sending creation message for nNetObject " << id << "\n";
01309 }
01310
01311 void nNetObject::GetID()
01312 {
01313 if ( !id && GetRefcount() >= 0 )
01314 {
01315 if ( bool( sn_Registrar ) && this == sn_Registrar->object )
01316 {
01317 id = sn_Registrar->id;
01318 }
01319 else
01320 {
01321 id = next_free();
01322 }
01323
01324 if (sn_netObjects[id])
01325 tERR_ERROR("Dublicate nNetObject id " << id);
01326
01327 sn_netObjectsOwner[id]=owner;
01328 sn_netObjects_AcceptClientSync[id]=false;
01329
01330 sn_netObjects[id]=this;
01331 }
01332 }
01333
01334
01335 void nNetObject::RequestSync(int user,bool ack){
01336 #ifdef nSIMULATE_PING
01337 ack=true;
01338 #endif
01339 this->GetID();
01340
01341 if (sn_GetNetState()==nSERVER || (AcceptClientSync() && owner==::sn_myNetID)){
01342 knowsAbout[user].syncReq=true;
01343 knowsAbout[user].nextSyncAck |=ack;
01344 }
01345 #ifdef DEBUG
01346 else
01347 tERR_ERROR("RequestSync should only be called server-side!");
01348 #endif
01349
01350 if ( syncListID_ < 0 )
01351 sn_SyncRequestedObject.Add( this, syncListID_ );
01352 }
01353
01354 void nNetObject::RequestSync(bool ack){
01355 this->GetID();
01356
01357 #ifdef nSIMULATE_PING
01358 ack=true;
01359 #endif
01360
01361 #ifdef DEBUG
01362 if (sn_GetNetState()==nCLIENT && (!AcceptClientSync() || owner!=::sn_myNetID))
01363 tERR_ERROR("RequestSync should only be called server-side!");
01364 #endif
01365
01366 for (int i=MAXCLIENTS;i>=0;i--){
01367 knowsAbout[i].syncReq=true;
01368 knowsAbout[i].nextSyncAck |=ack;
01369 }
01370
01371 if ( syncListID_ < 0 )
01372 sn_SyncRequestedObject.Add( this, syncListID_ );
01373 }
01374
01375
01376 static void net_control_handler(nMessage &m){
01377
01378 if (sn_GetNetState()==nSERVER){
01379 unsigned short id;
01380 m.Read(id);
01381 nNetObject *o = sn_netObjects[id];
01382 if ( o ){
01383 if (m.SenderID()==o->Owner())
01384
01385 o->ReceiveControlNet(m);
01386 else
01387 Cheater(m.SenderID());
01388 }
01389 }
01390 }
01391
01392 static nDescriptor net_control(23,net_control_handler,"net_control");
01393
01394 void nNetObject::ReceiveControlNet(nMessage &){
01395 #ifdef DEBUG
01396 if (sn_GetNetState()==nCLIENT)
01397 tERR_ERROR("rec_cont should not be called client-side!");
01398 #endif
01399
01400
01401
01402
01403 RequestSync();
01404 }
01405
01406
01407 nMessage * nNetObject::NewControlMessage(){
01408 nMessage *m=new nMessage(net_control);
01409 m->Write(id);
01410 return m;
01411 }
01412
01413
01414
01415 class nWaitForAckSync: public nWaitForAck{
01416 unsigned short netobj;
01417 public:
01418 nWaitForAckSync(nMessage* m,int rec,unsigned short obj)
01419 :nWaitForAck(m,rec),netobj(obj){
01420 if (sn_netObjects(obj)->knowsAbout[rec].acksPending<15)
01421 {
01422 sn_netObjects(obj)->knowsAbout[rec].acksPending++;
01423 }
01424 else
01425 {
01426 st_Breakpoint();
01427 }
01428 }
01429 virtual ~nWaitForAckSync(){
01430 tCHECK_DEST;
01431 }
01432
01433 virtual void AckExtraAction()
01434 {
01435 nNetObject* obj = sn_netObjects[netobj];
01436 if ( obj )
01437 {
01438 if ( obj->knowsAbout[receiver].acksPending)
01439 {
01440 obj->knowsAbout[receiver].acksPending--;
01441 }
01442 else
01443 {
01444
01445 }
01446
01447 #ifdef DEBUG
01448
01449
01450
01451
01452
01453
01454
01455
01456 #endif
01457
01458 obj->knowsAbout[receiver].knowsAboutExistence=true;
01459 }
01460 else
01461 {
01462
01463 }
01464 }
01465 };
01466
01467
01468
01469
01470 static void net_sync_handler(nMessage &m){
01471 unsigned short id;
01472 m.Read(id);
01473 #ifdef DEBUG
01474
01475 #endif
01476 nNetObject * obj = nNetObject::ObjectDangerous(id);
01477 if (obj){
01478 if (sn_GetNetState()!=nCLIENT &&
01479 (!obj->AcceptClientSync()
01480 || obj->Owner()!=m.SenderID())
01481 ){
01482 Cheater(m.SenderID());
01483 #ifdef DEBUG
01484 tERR_ERROR("sync should only be called client-side!");
01485 #endif
01486 }
01487 else if (obj->SyncIsNew(m)){
01488 m.Reset();
01489 m.Read(id);
01490 obj->ReadAll(m, false);
01491 }
01492 }
01493 }
01494
01495 static nDescriptor net_sync(24,net_sync_handler,"net_sync");
01496
01497 bool nNetObject::AcceptClientSync() const{
01498 return false;
01499 }
01500
01501
01502
01503
01504
01505
01506 static bool is_ready_to_get_objects[MAXCLIENTS+2];
01507
01508
01509
01510
01511 static bool s_DoPrintDebug = false;
01512 bool nNetObject::DoDebugPrint()
01513 {
01514 return s_DoPrintDebug;
01515 }
01516
01517 static int sn_syncedUser = -1;
01518
01520 int nNetObject::SyncedUser()
01521 {
01522 return sn_syncedUser;
01523 }
01524
01525 void nNetObject::SyncAll(){
01526 #ifdef DEBUG
01527 s_DoPrintDebug = false;
01528
01529 static nTimeRolling debugtime = 0;
01530 nTimeRolling time = tSysTimeFloat();
01531 if (time > debugtime && sn_GetNetState() == nSERVER)
01532 {
01533 debugtime = time+5;
01534
01535 }
01536 #endif
01537
01538 for (int user=MAXCLIENTS;user>=0;user--)
01539 if (is_ready_to_get_objects[user] &&
01540 sn_Connections[user].socket && sn_netObjects.Len()>0 && user!=sn_myNetID){
01541
01542 sn_syncedUser = user;
01543
01544
01545 if (destroyers[user])
01546 {
01547
01548 if ( destroyers[user]->DataLen() > 75 ||
01549 sn_Connections[user].sendBuffer_.Len() > 0 ||
01550 destroyersTime[user] < tSysTimeFloat()-.5 )
01551 {
01552 destroyers[user]->Send(user);
01553 destroyers[user]=NULL;
01554 }
01555 }
01556
01557
01558
01559 int currentSync = sn_SyncRequestedObject.Len()-1;
01560 while (sn_Connections[user].socket>0 &&
01561 sn_Connections[user].bandwidthControl_.CanSend() &&
01562 sn_Connections[user].ackPending<sn_maxNoAck &&
01563 currentSync >= 0){
01564 nNetObject *nos = sn_SyncRequestedObject( currentSync );
01565
01566 if (nos && nos->ClearToTransmit(user) && ( nos == sn_netObjects( nos->id ) )
01567 && (sn_GetNetState()!=nCLIENT ||
01568 nos->AcceptClientSync()))
01569 {
01570 short s = nos->id;
01571
01572 if (
01573 !nos->knowsAbout[user].knowsAboutExistence)
01574 {
01575 if (!nos->knowsAbout[user].acksPending){
01576 #ifdef DEBUG
01577
01578 #endif
01579
01580
01581
01582
01583
01584
01585 tJUST_CONTROLLED_PTR< nMessage > m=new nMessage
01586 (nos->CreatorDescriptor());
01587
01588 #ifdef DEBUG
01589 if (s == sn_WatchNetID)
01590 sn_WatchMessage = m;
01591 #endif
01592
01593 nos->WriteAll(*m,true);
01594 new nWaitForAckSync(m,user,s);
01595 unsigned long id = m->MessageIDBig();
01596 m->SendImmediately(user, false);
01597 m->messageIDBig_ = id;
01598
01599 nos->knowsAbout[user].syncReq = false;
01600 }
01601 #ifdef DEBUG
01602 else if (DoDebugPrint())
01603 {
01604 tString s;
01605 s << "Not remotely creating object ";
01606 nos->PrintName(s);
01607 s << " on user " << user << " again because there is an Ack pending.\n";
01608 con << s;
01609 }
01610 #endif
01611 }
01612 else if (nos->knowsAbout[user].syncReq
01613 && sn_Connections[user].bandwidthControl_.Control( nBandwidthControl::Usage_Planning ) >50
01614 && nos->knowsAbout[user].acksPending<=1){
01615
01616 tJUST_CONTROLLED_PTR< nMessage > m = new nMessage(net_sync);
01617
01618 m->Write(s);
01619 nos->WriteAll(*m,false);
01620 nos->knowsAbout[user].syncReq=false;
01621
01622 if (nos->knowsAbout[user].nextSyncAck){
01623 new nWaitForAckSync(m,user,s);
01624 nos->knowsAbout[user].nextSyncAck=false;
01625 }
01626 #ifndef nSIMULATE_PING
01627 unsigned long id = m->MessageIDBig();
01628
01629 m->SendImmediately(user,false);
01630 m->messageIDBig_ = id;
01631 #endif
01632 }
01633
01634 }
01635
01636 currentSync--;
01637 }
01638
01639 sn_syncedUser = -1;
01640
01641 #ifdef DEBUG
01642 bool inc=false;
01643 static int warn=0;
01644 static int nextWarnOverflow=0;
01645 static int nextWarnAck=0;
01646 if (sn_Connections[user].bandwidthControl_.Control( nBandwidthControl::Usage_Planning )<-100){
01647 if (warn>=nextWarnOverflow)
01648 {
01649 nextWarnOverflow = 2+(warn*17)/16;
01650 con << "Warning! Network overflow: "
01651 << -100-sn_Connections[user].bandwidthControl_.Control( nBandwidthControl::Usage_Planning ) << "\n";
01652 }
01653 inc=true;
01654 }
01655 if (sn_Connections[user].ackPending>=sn_maxNoAck){
01656 if (warn>=nextWarnAck)
01657 {
01658 nextWarnAck = 2+(warn*17)/16;
01659 std::cerr << "Warning! Too many acks pending: "
01660 << sn_Connections[user].ackPending << "\n";
01661 }
01662 inc=true;
01663 }
01664 if (inc)
01665 warn++;
01666 #endif
01667 }
01668
01669
01670
01671
01672 {
01673 for ( int currentSync = sn_SyncRequestedObject.Len()-1; currentSync >= 0; --currentSync ){
01674 nNetObject *nos = sn_SyncRequestedObject( currentSync );
01675
01676 if ( nos )
01677 {
01678
01679 bool canRemove = true;
01680
01681
01682 if ( nos == sn_netObjects( nos->id ) )
01683 {
01684 int start = ( sn_GetNetState() == nSERVER ) ? MAXCLIENTS : 0;
01685 int stop = ( sn_GetNetState() == nSERVER ) ? 1 : 0;
01686 for ( int i = start; i>=stop && canRemove; --i )
01687 {
01688 const nKnowsAboutInfo& knows = nos->knowsAbout[i];
01689 if ( sn_Connections[i].socket && knows.syncReq )
01690 canRemove = false;
01691 }
01692 }
01693 if ( canRemove )
01694 sn_SyncRequestedObject.Remove( nos, nos->syncListID_ );
01695 }
01696 }
01697 }
01698 }
01699
01700
01701 static void ready_handler(nMessage &m)
01702 {
01703 is_ready_to_get_objects[m.SenderID()]=true;
01704
01705
01706 sn_Connections[m.SenderID()].ping.Timestep(100);
01707 }
01708
01709 static nDescriptor ready(25,ready_handler,"ready to get objects");
01710
01711
01712 static void net_clear_handler(nMessage &m){
01713 if (sn_GetNetState()!=nSERVER){
01714 nNetObject::ClearAll();
01715 first_fill_ids();
01716 }
01717 }
01718
01719 static nDescriptor net_clear(26,net_clear_handler,"net_clear");
01720
01721
01722 void nNetObject::ClearAllDeleted()
01723 {
01724
01725
01726 nDeletedInfos swap;
01727 swap.swap( sn_netObjectsDeleted );
01728 swap.clear();
01729
01730
01731 for ( int i = MAXCLIENTS;i>=0;i--)
01732 {
01733 if ( sn_Connections[i].socket && destroyers[i] )
01734 {
01735 destroyers[i]->Send(i);
01736 destroyers[i] = NULL;
01737 }
01738 }
01739 }
01740
01741 void nNetObject::ClearAll(){
01742 ClearAllDeleted();
01743 sn_freedIDs.clear();
01744
01745
01746 int i;
01747 for (i=sn_netObjects.Len()-1;i>=0;i--)
01748 if (tJUST_CONTROLLED_PTR< nNetObject > no=sn_netObjects(i)){
01749 sn_netObjects(i)=NULL;
01750 sn_netObjectsOwner(i)=0;
01751 no->id = 0;
01752 }
01753 sn_netObjects.SetLen(0);
01754 sn_netObjectsOwner.SetLen(0);
01755
01756 for (i=sn_SyncRequestedObject.Len()-1;i>=0;i--)
01757 {
01758 nNetObject * n = sn_SyncRequestedObject[i];
01759 tASSERT(n);
01760 sn_SyncRequestedObject.Remove( n, n->syncListID_ );
01761 }
01762
01763 (tNEW(nMessage)(net_clear))->BroadCast();
01764 }
01765
01766
01767 void nNetObject::ClearKnows(int user, bool clear){
01768 if (0<=user && user <=MAXCLIENTS){
01769 is_ready_to_get_objects[user]=false;
01770 for (int i=sn_netObjects.Len()-1;i>=0;i--){
01771 nNetObject *no=sn_netObjects(i);
01772 if (no){
01773 no->knowsAbout[user].Reset();
01774
01775 no->DoBroadcastExistence();
01776
01777 if (clear){
01778 if (no->owner==user && user!=sn_myNetID){
01779 if (no->ActionOnQuit())
01780 sn_netObjects(i)=NULL;
01781 else{
01782 no->owner=::sn_myNetID;
01783 sn_netObjectsOwner(i)=::sn_myNetID;
01784 if (no->AcceptClientSync()){
01785 tControlledPTR< nNetObject > bounce( no );
01786 }
01787 }
01788 }
01789 }
01790 }
01791 }
01792 }
01793 }
01794
01795 void ClearKnows(int user, bool clear){
01796 nNetObject::ClearKnows(user, clear);
01797
01798 if (clear)
01799 for (int i=sn_netObjectsOwner.Len()-1;i>=0;i--){
01800 if (sn_netObjectsOwner(i)==user)
01801 sn_netObjectsOwner(i)=0;
01802 }
01803 }
01804
01805
01806
01807
01808
01809
01810
01811 void nNetObject::RelabelOnConnect(){
01812 if (sn_GetNetState()==nCLIENT){
01813 tArray<tJUST_CONTROLLED_PTR<nNetObject> > sn_netObjects_old;
01814
01815
01816 int i;
01817 for (i=sn_netObjects.Len()-1;i>=0;i--){
01818 sn_netObjects_old[i]=sn_netObjects(i);
01819 sn_netObjects(i)=NULL;
01820 sn_netObjectsOwner[i]=0;
01821 }
01822
01823
01824 for (i=sn_netObjects_old.Len()-1;i>=0;i--){
01825 nNetObject *no = sn_netObjects_old(i);
01826 if (no){
01827 unsigned short id=next_free();
01828
01829 #ifdef DEBUG
01830 sn_BreakOnObjectID( id );
01831 #endif
01832
01833 #ifdef DEBUG
01834
01835 #endif
01836 no->id=id;
01837 no->owner=::sn_myNetID;
01838 sn_netObjectsOwner[id]=::sn_myNetID;
01839 for (int j=MAXCLIENTS;j>=0;j--){
01840 no->knowsAbout[j].Reset();
01841 no->DoBroadcastExistence();
01842 }
01843
01844 if (sn_netObjects[id])
01845 st_Breakpoint();
01846
01847 sn_netObjects[id]=no;
01848 sn_netObjects_old(i)=NULL;
01849 }
01850 }
01851 }
01852 (new nMessage(ready))->Send(0);
01853 is_ready_to_get_objects[0]=true;
01854 }
01855
01856
01857 static void login_callback(){
01858 int user = nCallbackLoginLogout::User();
01859 ClearKnows( user, !nCallbackLoginLogout::Login() );
01860
01861 if ( user == 0 )
01862 {
01863 if (nCallbackLoginLogout::Login())
01864 nNetObject::RelabelOnConnect();
01865 else
01866 {
01867 sn_Destroyed.SetLen(0);
01868 sn_LocallyDestroyedIDs.clear();
01869 }
01870 }
01871
01872
01873 if ( destroyers[user] )
01874 {
01875 destroyers[user]->Send(user);
01876 destroyers[user]=NULL;
01877 }
01878 }
01879
01880 static nCallbackLoginLogout nlc(&login_callback);
01881
01882
01883 static bool sync_ack[MAXCLIENTS+2];
01884 static unsigned short c_sync=0;
01885
01886 static void sync_ack_handler(nMessage &m){
01887 unsigned short id;
01888 m.Read(id);
01889 if (id==c_sync)
01890 sync_ack[m.SenderID()]=true;
01891 }
01892
01893 static nDescriptor sync_ack_nd(27,sync_ack_handler,"sync_ack");
01894
01895
01896 static void sync_msg_handler(nMessage &m);
01897 static nDescriptor sync_nd(28,sync_msg_handler,"sync_msg");
01898
01899
01900
01901 void sn_Sync(REAL timeout,bool sync_sn_netObjects, bool otherEnd){
01902 nTimeAbsolute endTime=timeout+tSysTimeFloat();
01903
01904 #ifdef DEBUG
01905
01906 #endif
01907
01908 if (sn_GetNetState()==nCLIENT){
01909
01910 REAL failureProbability = 1;
01911 while ( failureProbability > .0001 && timeout > .01 )
01912 {
01913 failureProbability *= sn_Connections[0].PacketLoss();
01914
01915
01916
01917 static nVersionFeature sg_ServerSync( 10 );
01918
01919
01920 sync_ack[0]=true;
01921 if ( sg_ServerSync.Supported( 0 ) && otherEnd )
01922 {
01923 tJUST_CONTROLLED_PTR< nMessage > m=new nMessage(sync_nd);
01924 *m << timeout;
01925 m->Write(sync_sn_netObjects);
01926 m->Write(c_sync);
01927 m->Send(0);
01928 sync_ack[0]=false;
01929 }
01930 else
01931 {
01932
01933 failureProbability = 0;
01934 }
01935
01936
01937 while ( sn_Connections[0].socket && ( sync_ack[0] == false || sn_Connections[0].ackPending>0 || sn_QueueLen(0)) &&
01938 tSysTimeFloat()<endTime){
01939 sn_Delay();
01940 sn_Receive();
01941 if (sync_sn_netObjects)
01942 nNetObject::SyncAll();
01943 sn_SendPlanned();
01944 }
01945
01946
01947 timeout *= .5;
01948 endTime=timeout+tSysTimeFloat();
01949 }
01950 }
01951 else if (sn_GetNetState()==nSERVER){
01952 for (int user=MAXCLIENTS;user>0;user--){
01953 sync_ack[user]=false;
01954 if (sn_Connections[user].socket){
01955 tJUST_CONTROLLED_PTR< nMessage > m=new nMessage(sync_nd);
01956 *m << timeout;
01957 m->Write(sync_sn_netObjects);
01958 m->Write(c_sync);
01959 m->Send(user);
01960 }
01961 }
01962
01963 bool goon=true;
01964 while (goon){
01965 sn_Delay();
01966 sn_Receive();
01967 if (sync_sn_netObjects)
01968 nNetObject::SyncAll();
01969 sn_SendPlanned();
01970
01971 goon=false;
01972 for (int user=MAXCLIENTS;user>0;user--)
01973 {
01974 if (sn_Connections[user].socket &&
01975 (!sync_ack[user] || sn_Connections[user].ackPending>0 || sn_QueueLen(user)))
01976 {
01977 goon=true;
01978 }
01979 }
01980
01981 if (tSysTimeFloat()>endTime)
01982 {
01983 goon=false;
01984 }
01985 }
01986 }
01987
01988 #ifdef DEBUG
01989
01990 #endif
01991 }
01992
01993 static void sync_msg_handler(nMessage &m){
01994 static bool recursion=false;
01995 if (!recursion){
01996 recursion=true;
01997
01998 REAL timeout;
01999 unsigned short sync_sn_netObjects;
02000
02001
02002 m >> timeout;
02003 m.Read(sync_sn_netObjects);
02004 unsigned short c_sync;
02005 m.Read(c_sync);
02006
02007 if (sn_GetNetState()!=nSERVER){
02008 sn_Sync(timeout+4,sync_sn_netObjects!=0,false);
02009 tJUST_CONTROLLED_PTR< nMessage > m=new nMessage(sync_ack_nd);
02010 m->Write(c_sync);
02011 m->Send(0);
02012 }
02013 else
02014 {
02015
02016
02017 tJUST_CONTROLLED_PTR< nMessage > response=new nMessage(sync_ack_nd);
02018 response->Write(c_sync);
02019 response->Send(m.SenderID(),10000000);
02020 }
02021 recursion=false;
02022 }
02023 }
02024
02025 void clear_owners(){
02026 sn_freedIDs.clear();
02027 for (int i=sn_netObjectsOwner.Len()-1;i>=0;i--)
02028 sn_netObjectsOwner(i)=0;
02029 }
02030
02031
02032 #include "nPriorizing.h"
02033
02034
02035
02036
02037
02038 nBandwidthTaskObject::nBandwidthTaskObject( nType type, nNetObject& object )
02039 :nBandwidthTask( type ), object_( &object )
02040 {
02041 }
02042
02043 nBandwidthTaskObject::~nBandwidthTaskObject()
02044 {
02045
02046 }
02047
02048
02049 int nBandwidthTaskObject::DoEstimateSize() const
02050 {
02051 return 16;
02052 }
02053
02054
02055 void nBandwidthTaskSync::DoExecute( nSendBuffer& buffer, nBandwidthControl& control )
02056 {
02057 tJUST_CONTROLLED_PTR< nMessage > message = tNEW( nMessage )( net_sync );
02058 Object().WriteAll( *message, false );
02059 buffer.AddMessage( *message, &control );
02060 }
02061
02062
02063 void nBandwidthTaskCreate::DoExecute( nSendBuffer& buffer, nBandwidthControl& control )
02064 {
02065 tJUST_CONTROLLED_PTR< nMessage > message = tNEW( nMessage )( Object().CreatorDescriptor() );
02066 Object().WriteAll( *message, true );
02067
02068 buffer.AddMessage( *message, &control );
02069 }
02070
02071
02072
02073
02074
02075
02076
02080
02081
02082 nMachine & nNetObject::DoGetMachine( void ) const
02083 {
02084 return nMachine::GetMachine( Owner() );
02085 }
02086
02087