#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"
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< nNetObjectID > | sn_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 nNetObjectRegistrar * | sn_Registrar = NULL |
static tArray< nDestroyInfo > | sn_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< nNetObject > | sn_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 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 std::map< nNetObjectID, nDeletedInfo > nDeletedInfos |
Definition at line 154 of file nNetObject.cpp.
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
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 }
tDEFINE_REFOBJ | ( | nNetObject | ) | [pure virtual] |
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] |
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.
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] |
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().