void plNetClientMgr::IncNumInitialSDLStates() { fNumInitialSDLStates++; DebugMsg( "Received %d initial SDL states", fNumInitialSDLStates ); if ( GetFlagsBit( plNetClientApp::kNeedInitialAgeStateCount ) ) { DebugMsg( "Need initial SDL state count" ); return; } if ( GetNumInitialSDLStates()>=GetRequiredNumInitialSDLStates() ) { ICheckPendingStateLoad(hsTimer::GetSysSeconds()); NotifyRcvdAllSDLStates(); } }
// // main update fxn for net client code, return hsFail on err // int plNetClientMgr::Update(double secs) { int ret=hsOK; // ret code is unchecked, but what the hay if (GetFlagsBit(kDisableOnNextUpdate)) { SetFlagsBit(kDisableOnNextUpdate, false); IDisableNet(); } // Pump net messages NetCommUpdate(); static double lastUpdateTime=0; double curTime=hsTimer::GetSeconds(); if (curTime-lastUpdateTime > 1.f) { DebugMsg("NetClient hasn't updated for %f secs", curTime-lastUpdateTime); } lastUpdateTime=curTime; if (GetFlagsBit(kPlayingGame) ) { MaybeSendPendingPagingRoomMsgs(); ICheckPendingStateLoad(secs); ISendDirtyState(secs); IUpdateListenList(secs); if (GetFlagsBit(plNetClientApp::kShowLists)) IShowLists(); if (GetFlagsBit(plNetClientApp::kShowRooms)) IShowRooms(); if (GetFlagsBit(plNetClientApp::kShowAvatars)) IShowAvatars(); if (GetFlagsBit(plNetClientApp::kShowRelevanceRegions)) IShowRelevanceRegions(); } // Send dirty nodes, deliver vault callbacks, etc. VaultUpdate(); plNetLinkingMgr::GetInstance()->Update(); return ret; }
// Load Player object // a clone will be created if cloneNum>0 // returns the playerKey if successful. // // Don't call this directly. Send a clone message to the NetClientManager instead. // Load an object, optionally cloning if necessary. plKey plNetClientMgr::ILoadClone(plLoadCloneMsg *pCloneMsg) { plKey cloneKey = pCloneMsg->GetCloneKey(); if(pCloneMsg->GetIsLoading()) { if (cloneKey->ObjectIsLoaded()) { DebugMsg("ILoadClone: object %s is already loaded, ignoring", cloneKey->GetUoid().StringIze().c_str()); return cloneKey; } // check if local or remote player before loading plLoadAvatarMsg* loadAvMsg=plLoadAvatarMsg::ConvertNoRef(pCloneMsg); if (loadAvMsg) { bool originating = ( pCloneMsg->GetOriginatingPlayerID() == this->GetPlayerID() ); if (loadAvMsg->GetIsPlayer()) if (originating) fLocalPlayerKey = cloneKey; else AddRemotePlayerKey(cloneKey); else // hey, we got a quab or yeesha... or some other such devilry... AddNPCKey(cloneKey); } plKey cloneNodeKey = hsgResMgr::ResMgr()->FindKey(kNetClientCloneRoom_KEY); // Put the clone into the room, which also forces it to load. plNodeRefMsg* nodeRefCloneMsg = new plNodeRefMsg(cloneNodeKey, plNodeRefMsg::kOnRequest, -1, plNodeRefMsg::kObject); hsgResMgr::ResMgr()->AddViaNotify(cloneKey, nodeRefCloneMsg, plRefFlags::kActiveRef); // Finally, pump the dispatch system so all the new refs get delivered. ? plgDispatch::Dispatch()->MsgQueueProcess(); } else // we're unloading a clone { if (!cloneKey->ObjectIsLoaded()) { DebugMsg("ILoadClone: object %s is already unloaded, ignoring", cloneKey->GetName().c_str()); return cloneKey; } // need to drop our ref if it's an NPC // remote players handled by plPlayerPageMsg--don't sweat that plKeyVec::iterator it = std::find(fNPCKeys.begin(), fNPCKeys.end(), cloneKey); if (it != fNPCKeys.end()) fNPCKeys.erase(it); ICheckPendingStateLoad(hsTimer::GetSysSeconds()); plSynchEnabler p(false); // turn off dirty tracking while in this function GetKey()->Release(cloneKey); // undo the active ref we took in ILoadClone // send message to scene object to remove him from the room plNodeChangeMsg* nodeChange = new plNodeChangeMsg(GetKey(), cloneKey, nil); plgDispatch::MsgSend(nodeChange); } plKey requestorKey = pCloneMsg->GetRequestorKey(); // Readdress the message to the requestor and send it again plKey myKey = GetKey(); pCloneMsg->SetBCastFlag(plMessage::kNetPropagate, false); pCloneMsg->ClearReceivers(); pCloneMsg->AddReceiver(requestorKey); pCloneMsg->Ref(); // each message send unrefs once pCloneMsg->Send(); return cloneKey; }