BVB Source Codes

CRYENGINE Show GameClientChannel.cpp Source code

Return Download CRYENGINE: download GameClientChannel.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. /*************************************************************************
  4.    -------------------------------------------------------------------------
  5.    $Id$
  6.    $DateTime$
  7.  
  8.    -------------------------------------------------------------------------
  9.    History:
  10.    - 11:8:2004   11:40 : Created by M谩rcio Martins
  11.  
  12. *************************************************************************/
  13. #include "StdAfx.h"
  14. #include "GameClientChannel.h"
  15. #include "GameServerChannel.h"
  16. #include "GameContext.h"
  17. #include "CryAction.h"
  18. #include "GameRulesSystem.h"
  19. #include "GameObjects/GameObject.h"
  20. #include "GameClientNub.h"
  21. #include "ILevelSystem.h"
  22. #include "IActorSystem.h"
  23. #include "ActionGame.h"
  24. #include <CryNetwork/INetworkService.h>
  25. #include <CryNetwork/INetwork.h>
  26. #include "CryActionCVars.h"
  27.  
  28. #define LOCAL_ACTOR_VARIABLE     "g_localActor"
  29. #define LOCAL_CHANNELID_VARIABLE "g_localChannelId"
  30. #define LOCAL_ACTORID_VARIABLE   "g_localActorId"
  31.  
  32. //////////////////////////////////////////////////////////////////////////
  33.  
  34. #if defined(GAME_CHANNEL_SYNC_CLIENT_SERVER_TIME)
  35.  
  36. CClientClock::CClientClock(CGameClientChannel& clientChannel)
  37.         : m_clientChannel(clientChannel)
  38.         , m_pings(0)
  39.         , m_syncState(eSS_NotDone)
  40. {
  41.  
  42. }
  43.  
  44. void CClientClock::StartSync()
  45. {
  46.         m_syncState = eSS_Pinging;
  47.         m_pings = 0;
  48.  
  49.         SendSyncPing(0, gEnv->pTimer->GetAsyncTime());
  50. }
  51.  
  52. bool CClientClock::OnSyncTimeMessage(const SSyncTimeClient& messageParams)
  53. {
  54.         // Calculate the ping time
  55.         CTimeValue currentTime = gEnv->pTimer->GetAsyncTime();
  56.         const CTimeValue roundTripTime = currentTime - messageParams.originTime;
  57.         CTimeValue halfRoundTripTime = roundTripTime;
  58.         halfRoundTripTime /= 2;
  59.  
  60.         //CryLogAlways("Ping: %f", halfRoundTripTime.GetMilliSeconds());
  61.         m_pings += 1;
  62.  
  63.         const int initialPings = 8;
  64.         if ((m_syncState == eSS_Pinging) && (m_pings == initialPings))
  65.         {
  66.                 m_syncState = eSS_Refining;
  67.         }
  68.         else if (m_syncState == eSS_Refining)
  69.         {
  70.                 //float diff = CTimeValue(param.serverTimeActual - param.serverTimeGuess - halfRoundTripTime.GetValue()).GetMilliSeconds();
  71.                 //m_diffs.push_back(diff);
  72.  
  73.                 //float avgDiff = std::accumulate(m_diffs.begin(), m_diffs.end(), 0) / float(m_diffs.size());
  74.                 //CryLogAlways("Diff avg: %f", avgDiff);
  75.  
  76.                 if (m_pings > 32)
  77.                 {
  78.                         //CryLogAlways("Offset time: %f", m_OffsetTime.GetMilliSeconds());
  79.                         m_syncState = eSS_Done;
  80.                         return true;
  81.                 }
  82.         }
  83.  
  84.         m_timeOffsets.push_back(CTimeValue(messageParams.serverTimeActual) - CTimeValue(messageParams.originTime) - halfRoundTripTime);
  85.  
  86.         CTimeValue averageOffset;
  87.         if (m_timeOffsets.size() > 0)
  88.         {
  89.                 std::vector<CTimeValue> offsets = m_timeOffsets;
  90.  
  91.                 if (m_timeOffsets.size() > 3)
  92.                 {
  93.                         std::sort(offsets.begin(), offsets.end());
  94.  
  95.                         // remove the worst values from the list
  96.                         offsets.erase(offsets.end() - 1);
  97.                         offsets.erase(offsets.begin());
  98.                 }
  99.  
  100.                 for (std::vector<CTimeValue>::iterator it = offsets.begin(); it != offsets.end(); ++it)
  101.                 {
  102.                         averageOffset += *it;
  103.                 }
  104.                 averageOffset /= offsets.size();
  105.         }
  106.         m_serverTimeOffset = averageOffset;
  107.  
  108.         currentTime = gEnv->pTimer->GetAsyncTime();
  109.         const CTimeValue serverTimeEstimate = currentTime + m_serverTimeOffset;
  110.         SendSyncPing(messageParams.id + 1, currentTime, serverTimeEstimate);
  111.  
  112.         return true;
  113. }
  114.  
  115. void CClientClock::SendSyncPing(const int id, const CTimeValue currentTime, const CTimeValue serverTime /*= CTimeValue()*/)
  116. {
  117.         INetSendablePtr msg = new CSimpleNetMessage<SSyncTimeServer>(SSyncTimeServer(id, currentTime.GetValue(), serverTime.GetValue()), CGameServerChannel::SyncTimeServer);
  118.         m_clientChannel.GetNetChannel()->AddSendable(msg, 0, NULL, NULL);
  119. }
  120.  
  121. #endif //GAME_CHANNEL_SYNC_CLIENT_SERVER_TIME
  122.  
  123. //////////////////////////////////////////////////////////////////////////
  124.  
  125. CGameClientChannel::CGameClientChannel(INetChannel* pNetChannel, CGameContext* pContext, CGameClientNub* pNub)
  126.         : m_pNub(pNub)
  127.         , m_hasLoadedLevel(false)
  128. #if defined(GAME_CHANNEL_SYNC_CLIENT_SERVER_TIME)
  129.         , m_clock(*this)
  130. #endif
  131. {
  132.         pNetChannel->SetClient(pContext->GetNetContext());
  133.         Init(pNetChannel, pContext);
  134.  
  135. #if !NEW_BANDWIDTH_MANAGEMENT
  136.         INetChannel::SPerformanceMetrics pm;
  137.         if (!gEnv->bMultiplayer)
  138.                 pm.pPacketRateDesired = gEnv->pConsole->GetCVar("g_localPacketRate");
  139.         else
  140.                 pm.pPacketRateDesired = gEnv->pConsole->GetCVar("cl_packetRate");
  141.         pm.pBitRateDesired = gEnv->pConsole->GetCVar("cl_bandwidth");
  142.         pNetChannel->SetPerformanceMetrics(&pm);
  143. #endif // !NEW_BANDWIDTH_MANAGEMENT
  144.  
  145.         CRY_ASSERT(pNetChannel);
  146.         if (!CCryAction::GetCryAction()->IsGameSessionMigrating())
  147.         {
  148.                 // if we're migrating these globals are already setup to the correct variables
  149.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTORID_VARIABLE);
  150.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTOR_VARIABLE);
  151.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_CHANNELID_VARIABLE);
  152.         }
  153.  
  154.         CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_channelCreated, 0));
  155. }
  156.  
  157. CGameClientChannel::~CGameClientChannel()
  158. {
  159.         CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_channelDestroyed, 0));
  160.         m_pNub->ClientChannelClosed();
  161.  
  162.         if (!CCryAction::GetCryAction()->IsGameSessionMigrating())
  163.         {
  164.                 // if we're migrating these globals are already setup to the correct variables
  165.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTORID_VARIABLE);
  166.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTOR_VARIABLE);
  167.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_CHANNELID_VARIABLE);
  168.         }
  169.  
  170.         // If we're not migrating the host, restore the cached cvars.  If we *are*
  171.         // migrating the host, we need to preserve the current cvar settings in order
  172.         // to start the new server in the same manner.
  173.         if (!CCryAction::GetCryAction()->IsGameSessionMigrating())
  174.         {
  175.                 for (std::map<string, string>::iterator it = m_originalCVarValues.begin(); it != m_originalCVarValues.end(); ++it)
  176.                 {
  177.                         if (ICVar* pVar = gEnv->pConsole->GetCVar(it->first.c_str()))
  178.                         {
  179.                                 if (it->second != pVar->GetString())
  180.                                 {
  181.                                         CryLog("Restore cvar '%s' to '%s'", it->first.c_str(), it->second.c_str());
  182.                                 }
  183.                                 pVar->ForceSet(it->second.c_str());
  184.                         }
  185.                 }
  186.         }
  187. }
  188.  
  189. void CGameClientChannel::Release()
  190. {
  191.         delete this;
  192.         CryLogAlways("CGameClientChannel::Release");
  193. }
  194.  
  195. void CGameClientChannel::AddUpdateLevelLoaded(IContextEstablisher* pEst)
  196. {
  197.         if (!m_hasLoadedLevel)
  198.                 AddSetValue(pEst, eCVS_InGame, &m_hasLoadedLevel, true, "AllowChaining");
  199. }
  200.  
  201. bool CGameClientChannel::CheckLevelLoaded() const
  202. {
  203.         return m_hasLoadedLevel;
  204. }
  205.  
  206. void CGameClientChannel::OnDisconnect(EDisconnectionCause cause, const char* description)
  207. {
  208.         //CryLogAlways("CGameClientChannel::OnDisconnect(%d, %s)", cause, description?description:"");
  209.         CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_disconnected, int(cause), description));
  210.  
  211.         IGameRules* pGameRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules();
  212.         if (pGameRules)
  213.                 pGameRules->OnDisconnect(cause, description);
  214.  
  215.         if (IInput* pInput = gEnv->pInput)
  216.         {
  217.                 pInput->EnableDevice(eIDT_Keyboard, true);
  218.                 pInput->EnableDevice(eIDT_Mouse, true);
  219.         }
  220. }
  221.  
  222. void CGameClientChannel::DefineProtocol(IProtocolBuilder* pBuilder)
  223. {
  224.         pBuilder->AddMessageSink(this, CGameServerChannel::GetProtocolDef(), CGameClientChannel::GetProtocolDef());
  225.         CCryAction* cca = CCryAction::GetCryAction();
  226.         if (cca->GetIGameObjectSystem())
  227.                 cca->GetIGameObjectSystem()->DefineProtocol(false, pBuilder);
  228.         if (cca->GetGameContext())
  229.                 cca->GetGameContext()->DefineContextProtocols(pBuilder, false);
  230. }
  231.  
  232. // message implementation
  233. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, RegisterEntityClass, eNRT_ReliableUnordered, eMPF_BlocksStateChange)
  234. {
  235.         return GetGameContext()->RegisterClassName(param.name, param.id);
  236. }
  237.  
  238. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, RegisterEntityClassHash, eNRT_ReliableUnordered, eMPF_BlocksStateChange)
  239. {
  240.         CGameContext* pGameContext = GetGameContext();
  241.         uint32 localCrc = pGameContext->GetClassesHash();
  242.         if (localCrc != param.crc)
  243.         {
  244.                 pGameContext->DumpClasses();
  245.                 disconnectCause = eDC_ClassRegistryMismatch;
  246.                 disconnectMessage.Format("Server classes hash '%x' doesn't match local classes hash '%x'", param.crc, localCrc);
  247.                 return false;
  248.         }
  249.         return true;
  250. }
  251.  
  252. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, SetGameType, eNRT_ReliableOrdered, eMPF_BlocksStateChange)
  253. {
  254.         string rulesClass;
  255.         string levelName = param.levelName;
  256.         if (!GetGameContext()->ClassNameFromId(rulesClass, param.rulesClass))
  257.                 return false;
  258.         bool ok = true;
  259.         if (!GetGameContext()->SetImmersive(param.immersive))
  260.                 return false;
  261.         if (!bFromDemoSystem)
  262.         {
  263.                 CryLogAlways("Game rules class: %s", rulesClass.c_str());
  264.                 SGameContextParams params;
  265.                 params.levelName = levelName.c_str();
  266.                 params.gameRules = rulesClass.c_str();
  267.                 ok = GetGameContext()->ChangeContext(false, &params);
  268.         }
  269.         else
  270.         {
  271.                 GetGameContext()->SetLevelName(levelName.c_str());
  272.                 GetGameContext()->SetGameRules(rulesClass.c_str());
  273.                 //
  274.                 IActor* pDemoPlayPlayer = gEnv->pGameFramework->GetIActorSystem()->GetOriginalDemoSpectator();
  275.                 // clear all entities slot - because render data will be released in LoadLevel and these releases are not clears entities slots data (FogVolume for example)
  276.                 CScopedRemoveObjectUnlock unlockRemovals(CCryAction::GetCryAction()->GetGameContext());
  277.                 IEntityItPtr i = gEnv->pEntitySystem->GetEntityIterator();
  278.                 while (!i->IsEnd())
  279.                 {
  280.                         IEntity* pEnt = i->Next();
  281.                         //
  282.                         IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(pEnt->GetId());
  283.                         if (pActor && pActor == pDemoPlayPlayer)
  284.                         {
  285.                                 continue;
  286.                         }
  287.                         //
  288.                         pEnt->ClearFlags(ENTITY_FLAG_UNREMOVABLE);
  289.                         gEnv->pEntitySystem->RemoveEntity(pEnt->GetId(), true);
  290.                         //
  291.                 }
  292.                 //
  293.                 CCryAction::GetCryAction()->GetIGameRulesSystem()->CreateGameRules(rulesClass.c_str()); // we don't do context establishment tasks when playing back demo
  294.                 ok = CCryAction::GetCryAction()->GetILevelSystem()->LoadLevel(levelName.c_str()) != 0;
  295.                 //
  296.                 ILevelSystem* pLS = CCryAction::GetCryAction()->GetILevelSystem();
  297.                 if (pLS->GetCurrentLevel())
  298.                 {
  299.                         pLS->OnLoadingComplete(pLS->GetCurrentLevel());
  300.                 }
  301.                 if (pDemoPlayPlayer)
  302.                 {
  303.                         CCryAction::GetCryAction()->OnActionEvent(eAE_inGame);
  304.                 }
  305.         }
  306.  
  307.         return ok;
  308. }
  309.  
  310. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, ResetMap, eNRT_ReliableOrdered, eMPF_BlocksStateChange)
  311. {
  312.         GetGameContext()->ResetMap(false);
  313.         return true;
  314. }
  315.  
  316. NET_IMPLEMENT_IMMEDIATE_MESSAGE(CGameClientChannel, DefaultSpawn, eNRT_UnreliableOrdered, eMPF_BlocksStateChange | eMPF_DecodeInSync)
  317. {
  318.         bool bFromDemoSystem = nCurSeq == DEMO_PLAYBACK_SEQ_NUMBER && nOldSeq == DEMO_PLAYBACK_SEQ_NUMBER;
  319.  
  320. #if RESERVE_UNBOUND_ENTITIES
  321.         uint16 netMID;
  322.         ser.Value("partialNetID", netMID, 'eid');
  323. #endif
  324.  
  325.         SBasicSpawnParams param;
  326.         param.SerializeWith(ser);
  327.  
  328.         string actorClass;
  329.         if (!GetGameContext()->ClassNameFromId(actorClass, param.classId))
  330.                 return false;
  331.  
  332.         uint16 channelId = bFromDemoSystem ? (param.nChannelId != 0 ? -1 : 0) : param.nChannelId;
  333.  
  334.         IGameObjectSystem::SEntitySpawnParamsForGameObjectWithPreactivatedExtension userData;
  335.         userData.hookFunction = HookCreateActor;
  336.         userData.pUserData = &channelId;
  337.         userData.pSpawnSerializer = &ser;
  338.  
  339.         IEntitySystem* pEntitySystem = gEnv->pEntitySystem;
  340.         SEntitySpawnParams esp;
  341.         esp.id = 0;
  342. #if RESERVE_UNBOUND_ENTITIES
  343.         esp.id = GetGameContext()->GetNetContext()->RemoveReservedUnboundEntityMapEntry(netMID);
  344. #endif
  345.         esp.nFlags = (param.flags & ~ENTITY_FLAG_TRIGGER_AREAS);
  346.         esp.pClass = pEntitySystem->GetClassRegistry()->FindClass(actorClass);
  347.         if (!esp.pClass)
  348.                 return false;
  349.         esp.pUserData = &userData;
  350.         esp.qRotation = param.rotation;
  351.         esp.sName = param.name.c_str();
  352.         esp.vPosition = param.pos;
  353.         esp.vScale = param.scale;
  354.  
  355.         if (IEntity* pEntity = pEntitySystem->SpawnEntity(esp, false))
  356.         {
  357.                 const EntityId entityId = pEntity->GetId();
  358.                 if (!pEntitySystem->InitEntity(pEntity, esp))
  359.                 {
  360.                         return false;
  361.                 }
  362.  
  363.                 CGameObject* pGameObject = (CGameObject*)CCryAction::GetCryAction()->GetIGameObjectSystem()->CreateGameObjectForEntity(pEntity->GetId());
  364.                 CRY_ASSERT(pGameObject);
  365.                 if (param.bClientActor)
  366.                 {
  367.                         SetPlayerId(entityId);
  368.                 }
  369.                 GetGameContext()->GetNetContext()->SpawnedObject(entityId);
  370.                 pGameObject->PostRemoteSpawn();
  371.                 return true;
  372.         }
  373.  
  374.         pNetChannel->Disconnect(eDC_ContextCorruption, "Failed to spawn entity");
  375.  
  376.         return false;
  377. }
  378.  
  379. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, SetPlayerId_LocalOnly, eNRT_ReliableOrdered, eMPF_BlocksStateChange)
  380. {
  381.         if (!GetNetChannel()->IsLocal())
  382.                 return false;
  383.         SetPlayerId(param.id);
  384.         return true;
  385. }
  386.  
  387. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, SetConsoleVariable, eNRT_ReliableUnordered, eMPF_BlocksStateChange)
  388. {
  389.         if (GetNetChannel()->IsLocal() && !bFromDemoSystem)
  390.                 return false;
  391.  
  392.         return SetConsoleVar(param.key, param.value);
  393. }
  394.  
  395. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, SetBatchConsoleVariables, eNRT_ReliableUnordered, eMPF_BlocksStateChange)
  396. {
  397.         if (GetNetChannel()->IsLocal() && !bFromDemoSystem)
  398.                 return false;
  399.  
  400.         bool res = true;
  401.  
  402.         for (int i = 0; i < param.actual && res; ++i)
  403.                 res = SetConsoleVar(param.vars[i].key, param.vars[i].value);
  404.  
  405.         return res;
  406. }
  407.  
  408. void CGameClientChannel::SetPlayerId(EntityId id)
  409. {
  410.         CGameChannel::SetPlayerId(id);
  411.  
  412.         IScriptSystem* pSS = gEnv->pScriptSystem;
  413.  
  414.         if (id)
  415.         {
  416.                 ScriptHandle hdl;
  417.                 hdl.n = GetPlayerId();
  418.                 pSS->SetGlobalValue(LOCAL_ACTORID_VARIABLE, hdl);
  419.                 IEntity* pEntity = gEnv->pEntitySystem->GetEntity(id);
  420.                 if (pEntity)
  421.                 {
  422.                         IGameObject* pGameObject = CCryAction::GetCryAction()->GetGameObject(id);
  423.                         pSS->SetGlobalValue(LOCAL_ACTOR_VARIABLE, pEntity->GetScriptTable());
  424.                         pSS->SetGlobalValue(LOCAL_CHANNELID_VARIABLE, pGameObject ? pGameObject->GetChannelId() : 0);
  425.                 }
  426.                 else
  427.                 {
  428.                         pSS->SetGlobalToNull(LOCAL_ACTOR_VARIABLE);
  429.                         pSS->SetGlobalToNull(LOCAL_CHANNELID_VARIABLE);
  430.                 }
  431.  
  432.                 CallOnSetPlayerId();
  433.         }
  434.         else
  435.         {
  436.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTORID_VARIABLE);
  437.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_ACTOR_VARIABLE);
  438.                 gEnv->pScriptSystem->SetGlobalToNull(LOCAL_CHANNELID_VARIABLE);
  439.         }
  440. }
  441.  
  442. void CGameClientChannel::CallOnSetPlayerId()
  443. {
  444.         IEntity* pPlayer = gEnv->pEntitySystem->GetEntity(GetPlayerId());
  445.         if (!pPlayer)
  446.                 return;
  447.  
  448.         IScriptTable* pScriptTable = pPlayer->GetScriptTable();
  449.         if (pScriptTable)
  450.         {
  451.                 SmartScriptTable client;
  452.                 if (pScriptTable->GetValue("Client", client))
  453.                 {
  454.                         if (pScriptTable->GetScriptSystem()->BeginCall(client, "OnSetPlayerId"))
  455.                         {
  456.                                 pScriptTable->GetScriptSystem()->PushFuncParam(pScriptTable);
  457.                                 pScriptTable->GetScriptSystem()->EndCall();
  458.                         }
  459.                 }
  460.         }
  461.  
  462.         if (IActor* pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(GetPlayerId()))
  463.                 pActor->InitLocalPlayer();
  464.  
  465. #ifndef OLD_VOICE_SYSTEM_DEPRECATED
  466.         if (m_pVoiceController)
  467.                 m_pVoiceController->PlayerIdSet(id);
  468. #endif
  469.  
  470.         pPlayer->AddFlags(ENTITY_FLAG_LOCAL_PLAYER | ENTITY_FLAG_TRIGGER_AREAS);
  471. }
  472.  
  473. bool CGameClientChannel::HookCreateActor(IEntity* pEntity, IGameObject* pGameObject, void* pUserData)
  474. {
  475.         //[AlexMcC|23.11.09]: Set the ChannelId for remote obejcts at the same time as local objects
  476.         // (which is very early). Setting the ChannelId early like this means that we can trust
  477.         // IActor::IsPlayer() very early, such as in Player::Init().
  478.         // Copied from CActorSystem.cpp
  479.         if (pGameObject)
  480.         {
  481.                 pGameObject->SetChannelId(*static_cast<uint16*>(pUserData));
  482.         }
  483.         return true;
  484. }
  485. bool CGameClientChannel::SetConsoleVar(const string& key, const string& val)
  486. {
  487.         IConsole* pConsole = gEnv->pConsole;
  488.         ICVar* pVar = pConsole->GetCVar(key.c_str());
  489.         if (!pVar)
  490.         {
  491.                 CryLog("Server sets console variable '%s' to '%s'", key.c_str(), val.c_str());
  492.                 CryLog("   cvar not found, ignoring");
  493.                 return true;
  494.         }
  495.         int flags = pVar->GetFlags();
  496.         if ((flags & VF_NET_SYNCED) == 0)
  497.         {
  498.                 CryLog("Server sets console variable '%s' to '%s'", key.c_str(), val.c_str());
  499.                 CryLog("   cvar not synchronized, disconnecting");
  500.                 return false;
  501.         }
  502.  
  503.         if (val != pVar->GetString())
  504.                 CryLog("Server sets console variable '%s' to '%s'", key.c_str(), val.c_str());
  505.  
  506.         std::map<string, string>::iterator orit = m_originalCVarValues.lower_bound(key);
  507.         if (orit == m_originalCVarValues.end() || orit->first != key)
  508.                 m_originalCVarValues.insert(std::make_pair(key, pVar->GetString()));
  509.  
  510.         pVar->ForceSet(val.c_str());
  511.  
  512.         return true;
  513. }
  514.  
  515. #if defined(GAME_CHANNEL_SYNC_CLIENT_SERVER_TIME)
  516.  
  517. NET_IMPLEMENT_SIMPLE_ATSYNC_MESSAGE(CGameClientChannel, SyncTimeClient, eNRT_ReliableUnordered, eMPF_NoSendDelay)
  518. {
  519.         return m_clock.OnSyncTimeMessage(param);
  520. }
  521.  
  522. #endif
  523.  
downloadGameClientChannel.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top