src/network/nNetObject.cpp File Reference

#include "tMemManager.h"
#include "nNetObject.h"
#include "tLocale.h"
#include "nSimulatePing.h"
#include "tSysTime.h"
#include "tToDo.h"
#include "nObserver.h"
#include "nConfig.h"
#include "tRecorder.h"
#include <deque>
#include <set>
#include <map>
#include "nPriorizing.h"

Include dependency graph for nNetObject.cpp:

Go to the source code of this file.

Classes

struct  nDeletedInfo
struct  nDestroyInfo
class  nWaitForAckSync

Defines

#define ID_PREFETCH   50

Typedefs

typedef std::map< nNetObjectID,
nDeletedInfo
nDeletedInfos

Functions

 tDEFINE_REFOBJ (nNetObject) int sn_pingCharityServer=0
static unsigned short inc_id ()
static bool free_server (nNetObjectID id)
static unsigned short next_free_server_nokill ()
static int kill_id_hog ()
static void kill_id_hog_todo ()
static unsigned short next_free_server (bool kill)
void req_id_handler (nMessage &m)
void id_req_handler (nMessage &m)
unsigned short next_free ()
void first_fill_ids ()
void Cheater (int i)
bool sn_Update (unsigned short &old, unsigned short n)
bool sn_Update (unsigned long &old, unsigned long n)
bool sn_WasDeletedLocally (unsigned short id)
static void net_destroy_handler (nMessage &m)
static void sn_DoDestroy ()
static void net_control_handler (nMessage &m)
static void net_sync_handler (nMessage &m)
static void ready_handler (nMessage &m)
static void net_clear_handler (nMessage &m)
void ClearKnows (int user, bool clear)
static void login_callback ()
static void sync_ack_handler (nMessage &m)
static void sync_msg_handler (nMessage &m)
void sn_Sync (REAL timeout, bool sync_sn_netObjects, bool otherEnd)
void clear_owners ()

Variables

static unsigned short net_current_id = 1
static const unsigned short net_max_current_id_max = 32000
static const unsigned short net_max_current_id_min = 16000
static unsigned short net_max_current_id = net_max_current_id_min
unsigned short net_reserved_id [ID_PREFETCH]
unsigned short distribute = 0
unsigned short request = 0
tArray< unsigned short > sn_netObjectsOwner
static std::deque< nNetObjectIDsn_freedIDs
static tArray< bool > sn_netObjects_AcceptClientSync
tArray< tJUST_CONTROLLED_PTR
< nNetObject > > 
sn_netObjects (1024)
static const REAL nDeletedTimeout = 60.0f
static nDeletedInfos sn_netObjectsDeleted
static bool sg_todoKillHog = false
nDescriptor req_id (20, req_id_handler,"req_id")
nDescriptor id_req (21, id_req_handler,"id_req_handler")
static nNetObjectRegistrarsn_Registrar = NULL
static tArray< nDestroyInfosn_Destroyed
static std::set< unsigned short > sn_LocallyDestroyedIDs
static nCallbackReceivedComplete sn_ReceivedComplete (sn_DoDestroy)
static nDescriptor net_destroy (22, net_destroy_handler,"net_destroy")
static tJUST_CONTROLLED_PTR
< nMessage
destroyers [MAXCLIENTS+2]
static REAL destroyersTime [MAXCLIENTS+2]
static tList< nNetObjectsn_SyncRequestedObject
bool deb_net
static nDescriptor net_control (23, net_control_handler,"net_control")
static nDescriptor net_sync (24, net_sync_handler,"net_sync")
static bool is_ready_to_get_objects [MAXCLIENTS+2]
static bool s_DoPrintDebug = false
static int sn_syncedUser = -1
static nDescriptor ready (25, ready_handler,"ready to get objects")
static nDescriptor net_clear (26, net_clear_handler,"net_clear")
static nCallbackLoginLogout nlc & login_callback
static bool sync_ack [MAXCLIENTS+2]
static unsigned short c_sync = 0
static nDescriptor sync_ack_nd (27, sync_ack_handler,"sync_ack")
static nDescriptor sync_nd (28, sync_msg_handler,"sync_msg")


Define Documentation

#define ID_PREFETCH   50

Definition at line 105 of file nNetObject.cpp.

Referenced by first_fill_ids(), id_req_handler(), kill_id_hog(), next_free(), and req_id_handler().


Typedef Documentation

typedef std::map< nNetObjectID, nDeletedInfo > nDeletedInfos

Definition at line 154 of file nNetObject.cpp.


Function Documentation

void Cheater ( int  i  ) 

Definition at line 530 of file nNetObject.cpp.

References con, sn_Connections, and sn_DisconnectUser().

Referenced by nAuthentication::HandlePasswordRequest(), nNOInitialisator< T >::Init(), net_control_handler(), net_sync_handler(), new_destination_handler(), nNetObject::Object(), nNetObject::Register(), req_id_handler(), and sn_DoDestroy().

00531 {
00532     // anything to do at all?
00533     if (i != 0 && !sn_Connections[i].socket)
00534     {
00535         return;
00536     }
00537 
00538     con << "User " << i << " tried to cheat.\n";
00539     //  st_Breakpoint();
00540 
00541     if ( i == 0 )
00542         // terminate connection to server
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

void clear_owners (  ) 

Definition at line 2025 of file nNetObject.cpp.

References GrowingArrayBase::Len(), and sn_netObjectsOwner.

02025                    {
02026     sn_freedIDs.clear();
02027     for (int i=sn_netObjectsOwner.Len()-1;i>=0;i--)
02028         sn_netObjectsOwner(i)=0;
02029 }

Here is the call graph for this function:

void ClearKnows ( int  user,
bool  clear 
)

Definition at line 1795 of file nNetObject.cpp.

References nNetObject::ClearKnows(), GrowingArrayBase::Len(), and sn_netObjectsOwner.

01795                                      {
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 }

Here is the call graph for this function:

void first_fill_ids (  ) 

Definition at line 518 of file nNetObject.cpp.

References ID_PREFETCH, id_req, nCLIENT, request, sn_GetNetState(), and tERR_ERROR.

Referenced by login_accept_handler(), and net_clear_handler().

00518                      {
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static bool free_server ( nNetObjectID  id  )  [static]

Definition at line 157 of file nNetObject.cpp.

References nDeletedInfo::object_, sn_netObjects, nDeletedInfo::time_, tSysTimeFloat(), and nDeletedInfo::UnSet().

Referenced by next_free_server_nokill().

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             // clear the deletion info, but don't reuse the ID just yet
00179             deleted.UnSet();
00180             return false;
00181         }
00182     }
00183 
00184     return true;
00185 }

Here is the call graph for this function:

Here is the caller graph for this function:

void id_req_handler ( nMessage m  ) 

Definition at line 396 of file nNetObject.cpp.

References nMessage::End(), ID_PREFETCH, MAXCLIENTS, next_free_server(), nSERVER, nMessage::Read(), req_id, nMessage::SenderID(), and sn_GetNetState().

00396                                 {
00397     // Add security: keep clients from fetching too many ids
00398 
00399     if (sn_GetNetState()==nSERVER && m.SenderID()<=MAXCLIENTS)
00400     {
00401         if (m.End())
00402         { // old style request; send only one ID back.
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             //    con << "Assigning ID " << id << "\n";
00407             rep->Write(id);
00408             rep->Send(m.SenderID());
00409 
00410 #ifdef DEBUG
00411             //con << "distributed id " << net_current_id-1 << " to user " << m.SenderID() << '\n';
00412 #endif
00413         }
00414         else
00415         {
00416             // new style request: many IDs
00417             unsigned short num;
00418             m.Read(num);
00419 
00420             // but not too many. kick violators.
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;       // begin of the block of currently assigned IDs
00429             unsigned short block_len=0;         // and it's length
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)      // RLE for allocated IDs
00438                     block_len++;
00439                 else
00440                 {
00441                     if (block_len > 0)
00442                     {
00443                         //                    con << "Assigning block " << begin_block << " - " << begin_block + block_len - 1 << "\n";
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                 //            con << "Assigning block " << begin_block << " - " << begin_block + block_len - 1 << "\n";
00454                 rep->Write(begin_block);
00455                 rep->Write(block_len);
00456             }
00457 
00458             rep->Send(m.SenderID());
00459         }
00460     }
00461 }

Here is the call graph for this function:

static unsigned short inc_id (  )  [static]

Definition at line 92 of file nNetObject.cpp.

References net_max_current_id.

Referenced by next_free_server_nokill().

00092                               {
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 }

Here is the caller graph for this function:

static int kill_id_hog (  )  [static]

Definition at line 239 of file nNetObject.cpp.

References con, ID_PREFETCH, GrowingArrayBase::Len(), MAXCLIENTS, sn_DisconnectUser(), sn_netObjects, sn_netObjectsOwner, and st_Breakpoint().

Referenced by kill_id_hog_todo().

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     // find out how many IDs a user has reserved with or without using them
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     // find the user with most used/grabbed IDs
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     // kick the top grabber
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     // kick the top user
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void kill_id_hog_todo (  )  [static]

Definition at line 312 of file nNetObject.cpp.

References kill_id_hog().

Referenced by next_free_server().

00313 {
00314     if ( sg_todoKillHog )
00315         kill_id_hog();
00316     sg_todoKillHog=false;
00317 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void login_callback (  )  [static]

Definition at line 1857 of file nNetObject.cpp.

References nNetObject::ClearKnows(), nCallbackLoginLogout::Login(), NULL, nNetObject::RelabelOnConnect(), tArray< T, MALLOC >::SetLen(), and nCallbackLoginLogout::User().

01857                             {
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     // send and delete the  remaining destroyer message
01873     if ( destroyers[user] )
01874     {
01875         destroyers[user]->Send(user);
01876         destroyers[user]=NULL;
01877     }
01878 }

Here is the call graph for this function:

static void net_clear_handler ( nMessage m  )  [static]

Definition at line 1712 of file nNetObject.cpp.

References nNetObject::ClearAll(), first_fill_ids(), nSERVER, and sn_GetNetState().

01712                                           {
01713     if (sn_GetNetState()!=nSERVER){
01714         nNetObject::ClearAll();
01715         first_fill_ids();
01716     }
01717 }

Here is the call graph for this function:

static void net_control_handler ( nMessage m  )  [static]

Definition at line 1376 of file nNetObject.cpp.

References Cheater(), nNetObject::id, nSERVER, nNetObject::Owner(), nMessage::Read(), nNetObject::ReceiveControlNet(), nMessage::SenderID(), sn_GetNetState(), and sn_netObjects.

01376                                             {
01377     //con << "control\n";
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()) // only the owner is
01384                 // allowed to control the object
01385                 o->ReceiveControlNet(m);
01386             else
01387                 Cheater(m.SenderID()); // another lame cheater.
01388         }
01389     }
01390 }

Here is the call graph for this function:

static void net_destroy_handler ( nMessage m  )  [static]

Definition at line 872 of file nNetObject.cpp.

References nDestroyInfo::actionOnDeleteExecuted, nMessage::End(), nDestroyInfo::id, nNetObject::id, GrowingArrayBase::Len(), nMessage::Read(), nDestroyInfo::sender, nMessage::SenderID(), tArray< T, MALLOC >::SetLen(), sn_netObjects, sn_WasDeletedLocally(), tASSERT, nDestroyInfo::timeout, and tSysTimeFloat().

00872                                             {
00873     //con << "destroy begin\n";
00874     unsigned short id;
00875     //int count=0;
00876     while (!m.End()){
00877         m.Read(id);
00878 #ifdef DEBUG
00879         sn_BreakOnObjectID( id );
00880 #endif
00881         // see if there was a local destruction; if yes, ignore.
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         // notify object of pending deletion
00892         if (nNetObject *no=sn_netObjects[id])
00893         {
00894             tASSERT( !no->Owned() );
00895 
00896             no->ActionOnDelete();
00897             info.actionOnDeleteExecuted=true;
00898 
00899             // if the object is now suddenly owned by this machine, there must be a reason.
00900             // undo the deletion. Whoever did this has now the responsibility for the object.
00901             if ( no->Owned() )
00902                 sn_Destroyed.SetLen( sn_Destroyed.Len() - 1 );
00903         }
00904 
00905 #ifdef DEBUG
00906         //count ++;
00907         //con << count;
00908         //con << " destroying object " << id << " by remote order.\n";
00909 #endif
00910 
00911     }
00912     //con << "destroy end.\n";
00913 }

Here is the call graph for this function:

static void net_sync_handler ( nMessage m  )  [static]

Definition at line 1470 of file nNetObject.cpp.

References nNetObject::AcceptClientSync(), Cheater(), nNetObject::id, nCLIENT, nNetObject::ObjectDangerous(), nNetObject::Owner(), nMessage::Read(), nNetObject::ReadAll(), nMessage::Reset(), nMessage::SenderID(), sn_GetNetState(), nNetObject::SyncIsNew(), and tERR_ERROR.

01470                                          {
01471     unsigned short id;
01472     m.Read(id);
01473 #ifdef DEBUG
01474     // sn_BreakOnObjectID( id );
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 }

Here is the call graph for this function:

unsigned short next_free (  ) 

Definition at line 465 of file nNetObject.cpp.

References con, ID_PREFETCH, id_req, nCLIENT, next_free_server(), request, sn_Connections, sn_GetNetState(), sn_netObjects, sn_Receive(), sn_SendPlanned(), nNetObject::SyncAll(), tAdvanceFrame(), tERR_ERROR_INT, and tSysTimeFloat().

Referenced by nNetObject::GetID(), and nNetObject::RelabelOnConnect().

00465                           {
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                 // wait for new ids from the server
00483 #ifdef DEBUG
00484                 // con << distribute << ":" << request << '\n';
00485 #endif
00486                 sn_Receive();
00487                 nNetObject::SyncAll();
00488                 sn_SendPlanned();
00489                 //      st_Breakpoint();
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             //      con << "used id " << ret << '\n';
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned short next_free_server ( bool  kill  )  [static]

Definition at line 319 of file nNetObject.cpp.

References con, increase(), kill_id_hog_todo(), net_max_current_id, next_free_server_nokill(), and st_ToDo().

Referenced by id_req_handler(), and next_free().

00319                                                    {
00320     nNetObjectID id = next_free_server_nokill();
00321     if ( id > 0 )
00322     {
00323         return id;
00324     }
00325     else
00326     {
00327         // plan to kill the worst ID user
00328         sg_todoKillHog=true;
00329         st_ToDo( kill_id_hog_todo );
00330 
00331         // increase ID limit
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             // throw an error
00346             if ( kill )
00347                 throw nKillHim();
00348 
00349             // or just exit silently
00350             con << "Emergency exit: desperately ran out of IDs.\n";
00351             exit(-1);
00352         }
00353     }
00354 }

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned short next_free_server_nokill (  )  [static]

Definition at line 187 of file nNetObject.cpp.

References free_server(), inc_id(), net_max_current_id, nSERVER, nSTANDALONE, sn_GetNetState(), and tERR_ERROR.

Referenced by next_free_server().

00187                                                {
00188     // slowly decrease max user ID
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     // recycle old used IDs
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             // no problem!
00219 #ifdef DEBUG
00220             sn_BreakOnObjectID( net_current_id );
00221 #endif
00222             return net_current_id;
00223         }
00224         else
00225         {
00226             // we ran out of IDs.
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 }

Here is the call graph for this function:

Here is the caller graph for this function:

static void ready_handler ( nMessage m  )  [static]

Definition at line 1701 of file nNetObject.cpp.

References nConnectionInfo::ping, nMessage::SenderID(), sn_Connections, and nPingAverager::Timestep().

01702 {
01703     is_ready_to_get_objects[m.SenderID()]=true;
01704 
01705     // reset peer's ping, it's probably unreliable
01706     sn_Connections[m.SenderID()].ping.Timestep(100);
01707 }

Here is the call graph for this function:

void req_id_handler ( nMessage m  ) 

Definition at line 356 of file nNetObject.cpp.

References Cheater(), con, nMessage::End(), ID_PREFETCH, nMessage::MessageID(), nSERVER, nMessage::Read(), request, nMessage::SenderID(), sn_GetNetState(), and sn_netObjects.

00356                                 {
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                     // con << "got id " << net_reserved_id[request] << '\n';
00384 #endif
00385                     request++;
00386                     if (request>=ID_PREFETCH)
00387                         request=0;
00388                 }
00389             }
00390         }
00391     }
00392 }

Here is the call graph for this function:

static void sn_DoDestroy (  )  [static]

Definition at line 915 of file nNetObject.cpp.

References nNetObject::ActionOnDelete(), nDestroyInfo::actionOnDeleteExecuted, Cheater(), nDestroyInfo::id, GrowingArrayBase::Len(), NULL, nNetObject::Owner(), nDestroyInfo::sender, tArray< T, MALLOC >::SetLen(), sn_Destroyed, sn_netObjects, sn_netObjectsOwner, sn_WasDeletedLocally(), tASSERT, nDestroyInfo::timeout, and tSysTimeFloat().

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         // check if the message timed out
00929         bool timedOut = ( info.timeout < tSysTimeFloat() );
00930 
00931         // get object
00932         nNetObject *no=sn_netObjects[id];
00933 
00934         // destroy it!
00935         if (bool(no) || timedOut){
00936 #ifdef DEBUG
00937             sn_BreakOnObjectID( id );
00938 #endif
00939             // see if there was a local destruction; if yes, ignore.
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             // delete message by overwriting it with the last message in the array
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 }

Here is the call graph for this function:

void sn_Sync ( REAL  timeout,
bool  sync_sn_netObjects,
bool  otherEnd 
)

Definition at line 1901 of file nNetObject.cpp.

References MAXCLIENTS, nCLIENT, nSERVER, nConnectionInfo::PacketLoss(), REAL, sn_Connections, sn_Delay(), sn_GetNetState(), sn_QueueLen(), sn_Receive(), sn_SendPlanned(), nVersionFeature::Supported(), sync_nd, nNetObject::SyncAll(), and tSysTimeFloat().

Referenced by gGame::StateUpdate(), sync_msg_handler(), and gGame::SyncState().

01901                                                                  {
01902     nTimeAbsolute endTime=timeout+tSysTimeFloat();
01903 
01904 #ifdef DEBUG
01905     //con << "Start sync...\n";
01906 #endif
01907 
01908     if (sn_GetNetState()==nCLIENT){
01909         // repeat as often as packet loss suggests: of 100 packets, we want a single lost packet left probability of 1%.
01910         REAL failureProbability = 1;
01911         while ( failureProbability > .0001 && timeout > .01 )
01912         {
01913             failureProbability *= sn_Connections[0].PacketLoss();
01914             // con << failureProbability << "\n";
01915 
01916             // server responding to sync request message
01917             static nVersionFeature sg_ServerSync( 10 );
01918 
01919             // ask server when we're fully synced from his side
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                 // repeating the procedure is useless anyway
01933                 failureProbability = 0;
01934             }
01935 
01936             // wait for all packets to be sent and the sync ack packet to be received
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             // decrease timeout for next try
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     //con << "Stop sync.\n";
01990 #endif
01991 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool sn_Update ( unsigned long &  old,
unsigned long  n 
)

Definition at line 674 of file nNetObject.cpp.

00674                                                   {
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 }

bool sn_Update ( unsigned short &  old,
unsigned short  n 
)

Definition at line 657 of file nNetObject.cpp.

Referenced by gCycle::ReadSync(), nConfItemBase::s_GetConfigMessage(), and nNetObject::SyncIsNew().

00657                                                     {
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 }

Here is the caller graph for this function:

bool sn_WasDeletedLocally ( unsigned short  id  ) 

Definition at line 845 of file nNetObject.cpp.

Referenced by nNetObject::InitAfterCreation(), net_destroy_handler(), and sn_DoDestroy().

00846 {
00847     // delete local destruction log, if there was any
00848     std::set< unsigned short >::iterator found = sn_LocallyDestroyedIDs.find(id);
00849     if ( found != sn_LocallyDestroyedIDs.end() )
00850     {
00851         // yes. Ignore the message and remove the local destroy thing.
00852         sn_LocallyDestroyedIDs.erase( found );
00853         return true;
00854     }
00855 
00856     return false;
00857 }

Here is the caller graph for this function:

static void sync_ack_handler ( nMessage m  )  [static]

Definition at line 1886 of file nNetObject.cpp.

References nNetObject::id, nMessage::Read(), and nMessage::SenderID().

01886                                          {
01887     unsigned short id;
01888     m.Read(id);
01889     if (id==c_sync)
01890         sync_ack[m.SenderID()]=true;
01891 }

Here is the call graph for this function:

static void sync_msg_handler ( nMessage m  )  [static]

Definition at line 1993 of file nNetObject.cpp.

References nSERVER, nMessage::Read(), REAL, nMessage::SenderID(), sn_GetNetState(), sn_Sync(), and sync_ack_nd.

01993                                          {
01994     static bool recursion=false;
01995     if (!recursion){
01996         recursion=true;
01997 
01998         REAL timeout;
01999         unsigned short sync_sn_netObjects;
02000 
02001         // sync and write sync response
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             // no time for syncing! write sync response immediately with low priority so the client
02016             // gets it as soon as all other things are sent
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 }

Here is the call graph for this function:

tDEFINE_REFOBJ ( nNetObject   )  [pure virtual]


Variable Documentation

unsigned short c_sync = 0 [static]

Definition at line 1884 of file nNetObject.cpp.

bool deb_net

Definition at line 153 of file nNetwork.cpp.

tJUST_CONTROLLED_PTR< nMessage > destroyers[MAXCLIENTS+2] [static]

Definition at line 978 of file nNetObject.cpp.

REAL destroyersTime[MAXCLIENTS+2] [static]

Definition at line 979 of file nNetObject.cpp.

unsigned short distribute = 0

Definition at line 109 of file nNetObject.cpp.

nDescriptor id_req(21, id_req_handler,"id_req_handler")

Referenced by first_fill_ids(), and next_free().

bool is_ready_to_get_objects[MAXCLIENTS+2] [static]

Definition at line 1506 of file nNetObject.cpp.

nCallbackLoginLogout nlc& login_callback [static]

Definition at line 1880 of file nNetObject.cpp.

const REAL nDeletedTimeout = 60.0f [static]

Definition at line 125 of file nNetObject.cpp.

nDescriptor net_clear(26, net_clear_handler,"net_clear") [static]

Referenced by nNetObject::ClearAll().

nDescriptor net_control(23, net_control_handler,"net_control") [static]

Referenced by nNetObject::NewControlMessage().

unsigned short net_current_id = 1 [static]

Definition at line 59 of file nNetObject.cpp.

nDescriptor net_destroy(22, net_destroy_handler,"net_destroy") [static]

Referenced by nNetObject::~nNetObject().

unsigned short net_max_current_id = net_max_current_id_min [static]

Definition at line 72 of file nNetObject.cpp.

Referenced by inc_id(), next_free_server(), and next_free_server_nokill().

const unsigned short net_max_current_id_max = 32000 [static]

Definition at line 63 of file nNetObject.cpp.

const unsigned short net_max_current_id_min = 16000 [static]

Definition at line 68 of file nNetObject.cpp.

unsigned short net_reserved_id[ID_PREFETCH]

Definition at line 108 of file nNetObject.cpp.

nDescriptor net_sync(24, net_sync_handler,"net_sync") [static]

Referenced by nBandwidthTaskSync::DoExecute(), and nNetObject::SyncAll().

nDescriptor ready(25, ready_handler,"ready to get objects") [static]

Referenced by nNetObject::RelabelOnConnect().

nDescriptor req_id(20, req_id_handler,"req_id")

Referenced by id_req_handler().

unsigned short request = 0

Definition at line 109 of file nNetObject.cpp.

Referenced by first_fill_ids(), next_free(), and req_id_handler().

bool s_DoPrintDebug = false [static]

Definition at line 1511 of file nNetObject.cpp.

bool sg_todoKillHog = false [static]

Definition at line 311 of file nNetObject.cpp.

tArray< nDestroyInfo > sn_Destroyed [static]

Definition at line 841 of file nNetObject.cpp.

Referenced by sn_DoDestroy().

std::deque<nNetObjectID> sn_freedIDs [static]

Definition at line 117 of file nNetObject.cpp.

std::set< unsigned short > sn_LocallyDestroyedIDs [static]

Definition at line 842 of file nNetObject.cpp.

tArray<tJUST_CONTROLLED_PTR<nNetObject> > sn_netObjects(1024)

Referenced by nWaitForAckSync::AckExtraAction(), nNetObject::ClearAll(), nNetObject::ClearKnows(), free_server(), nNetObject::GetID(), nNetObject::GetRefcount(), zValidator::isOwner(), zValidator::isTeamOwner(), zShape::joinWithZone(), kill_id_hog(), net_control_handler(), net_destroy_handler(), next_free(), nWaitForAckSync::nWaitForAckSync(), nNetObject::Object(), nNetObject::ObjectDangerous(), zZone::ReadSync(), nNetObject::Register(), nNetObject::RelabelOnConnect(), nNetObject::Release(), req_id_handler(), zSelectorSingleDeadOwner::select(), zSelectorOwnerTeamTeammate::select(), zSelectorOwnerTeam::select(), zSelectorOwner::select(), sn_DoDestroy(), gGame::StateUpdate(), nNetObject::SyncAll(), and nNetObject::~nNetObject().

tArray<bool> sn_netObjects_AcceptClientSync [static]

Definition at line 120 of file nNetObject.cpp.

nDeletedInfos sn_netObjectsDeleted [static]

Definition at line 155 of file nNetObject.cpp.

tArray<unsigned short> sn_netObjectsOwner

Definition at line 113 of file nNetObject.cpp.

Referenced by clear_owners(), nNetObject::ClearAll(), ClearKnows(), nNetObject::ClearKnows(), kill_id_hog(), and sn_DoDestroy().

nCallbackReceivedComplete sn_ReceivedComplete(sn_DoDestroy) [static]

nNetObjectRegistrar* sn_Registrar = NULL [static]

Definition at line 721 of file nNetObject.cpp.

int sn_syncedUser = -1 [static]

Definition at line 1517 of file nNetObject.cpp.

tList< nNetObject > sn_SyncRequestedObject [static]

Definition at line 982 of file nNetObject.cpp.

Referenced by nNetObject::SyncAll().

bool sync_ack[MAXCLIENTS+2] [static]

Definition at line 1883 of file nNetObject.cpp.

nDescriptor sync_ack_nd(27, sync_ack_handler,"sync_ack") [static]

Referenced by sync_msg_handler().

nDescriptor sync_nd(28, sync_msg_handler,"sync_msg") [static]

Referenced by sn_Sync().


Generated on Sat Mar 15 23:00:56 2008 for Armagetron Advanced by  doxygen 1.5.4