EContextEstablishTaskResult OnStep( SContextEstablishState& state ) { CCryAction * pFramework = CCryAction::GetCryAction(); if (CGameClientNub * pClientNub = pFramework->GetGameClientNub()) { CGameClientChannel * pChannel = pClientNub->GetGameClientChannel(); if (pChannel) { switch (pChannel->GetClock().GetSyncState()) { case CClientClock::eSS_NotDone: { pChannel->GetClock().StartSync(); } break; case CClientClock::eSS_Done: { return eCETR_Ok; } break; } } } return eCETR_Wait; }
// send a call int CScriptRMI::ProxyFunction( IFunctionHandler* pH, void *pBuffer, int nSize ) { if (!m_pThis->m_pParent) { pH->GetIScriptSystem()->RaiseError( "Trying to proxy a remote method invocation with no game started... failing" ); return pH->EndFunction(); } string funcInfo; string dispatchInfo; bool gatherDebugInfo = pLogRMIEvents && pLogRMIEvents->GetIVal() != 0; IScriptSystem * pSS = pH->GetIScriptSystem(); const SFunctionInfo * pFunctionInfo = static_cast<const SFunctionInfo *>(pBuffer); SmartScriptTable proxyTable; if (!pH->GetParam( 1, proxyTable )) return pH->EndFunction( false ); ScriptHandle flags; ScriptHandle id; if (!proxyTable->GetValue(FLAGS_FIELD, flags)) return pH->EndFunction( false ); if (!proxyTable->GetValue(ID_FIELD, id)) return pH->EndFunction( false ); int formatStart = 2; if (uint32 flagsMask = flags.n & (eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels)) { if (flagsMask != (eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels)) formatStart ++; } _smart_ptr<CScriptMessage> pMsg = new CScriptMessage( pFunctionInfo->reliability, pFunctionInfo->attachment, (EntityId)id.n, pFunctionInfo->funcID, pFunctionInfo->format ); if (!pMsg->SetFromFunction( pH, formatStart )) { return pH->EndFunction( false ); } if (gatherDebugInfo) funcInfo = pMsg->DebugInfo(); INetContext * pNetContext = m_pThis->m_pParent->GetNetContext(); CCryAction * pFramework = m_pThis->m_pParent->GetFramework(); if (flags.n & eDF_ToServer) { CGameClientNub * pClientNub = pFramework->GetGameClientNub(); bool called = false; if (pClientNub) { CGameClientChannel * pChannel = pClientNub->GetGameClientChannel(); if (pChannel) { DispatchRMI( pChannel->GetNetChannel(), pMsg, false ); called = true; } } if (!called) { pSS->RaiseError( "RMI via client (to server) requested but we are not a client" ); } if (gatherDebugInfo) dispatchInfo = "server"; } else if (flags.n & (eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels)) { CGameServerNub * pServerNub = pFramework->GetGameServerNub(); if (pServerNub) { int myChannelId = 0; bool ok = true; if (flags.n != (eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels)) { if (!pH->GetParam( 2, myChannelId )) { pSS->RaiseError( "RMI onClient or otherClients must have a valid channel id for its first argument" ); ok = false; } else if (pServerNub->GetServerChannelMap()->find(myChannelId) == pServerNub->GetServerChannelMap()->end()) { pSS->RaiseError( "RMI No such server channel %d", myChannelId ); ok = false; } } if (ok) { TServerChannelMap * pChannelMap = pServerNub->GetServerChannelMap(); for (TServerChannelMap::iterator iter = pChannelMap->begin(); iter != pChannelMap->end(); ++iter) { bool isOwn = iter->first == myChannelId; if (isOwn && !(flags.n & eDF_ToClientOnChannel)) continue; if (!isOwn && !(flags.n & eDF_ToClientOnOtherChannels)) continue; if (iter->second->GetNetChannel()) DispatchRMI( iter->second->GetNetChannel(), pMsg, true ); } if (gatherDebugInfo) { dispatchInfo = "client: "; bool appendChannel = false; switch (flags.n) { case eDF_ToClientOnChannel: dispatchInfo += "specificChannel"; appendChannel = true; break; case eDF_ToClientOnOtherChannels: dispatchInfo += "otherChannels"; appendChannel = true; break; case eDF_ToClientOnChannel | eDF_ToClientOnOtherChannels: dispatchInfo += "allChannels"; break; default: dispatchInfo += "UNKNOWN(BUG)"; appendChannel = true; CRY_ASSERT(false); } if (appendChannel) { string temp; temp.Format(" %d", myChannelId); dispatchInfo += temp; } } } } else { pSS->RaiseError( "RMI via server (to client) requested but we are not a server" ); } } if (gatherDebugInfo) { IEntity * pEntity = gEnv->pEntitySystem->GetEntity((EntityId)id.n); const char * name = "<invalid>"; if (pEntity) name = pEntity->GetName(); CryLogAlways("[rmi] %s(%s) [%s] on entity[%d] %s", pH->GetFuncName(), funcInfo.c_str(), dispatchInfo.c_str(), (int)id.n, name); } return pH->EndFunction( true ); }