BVB Source Codes

CRYENGINE Show CryAction.cpp Source code

Return Download CRYENGINE: download CryAction.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.    - 20:7:2004   11:07 : Created by Marco Koegler
  11.    - 3:8:2004           16:00 : Taken-ver by Marcio Martins
  12.    - 2005              : Changed by everyone
  13.  
  14. *************************************************************************/
  15. #include "StdAfx.h"
  16. #include "CryAction.h"
  17.  
  18. #define PRODUCT_VERSION_MAX_STRING_LENGTH (256)
  19.  
  20. //#define CRYACTION_DEBUG_MEM   // debug memory usage
  21.  
  22. #if CRY_PLATFORM_WINDOWS
  23.         #include <CryCore/Platform/CryWindows.h>
  24.         #include <ShellApi.h>
  25. #endif
  26.  
  27. #include <CryCore/Platform/CryLibrary.h>
  28. #include <CryCore/Platform/platform_impl.inl>
  29.  
  30. #include "AIDebugRenderer.h"
  31. #include "GameRulesSystem.h"
  32. #include "ScriptBind_ActorSystem.h"
  33. #include "ScriptBind_ItemSystem.h"
  34. #include "ScriptBind_Inventory.h"
  35. #include "ScriptBind_ActionMapManager.h"
  36. #include "Network/ScriptBind_Network.h"
  37. #include "ScriptBind_Action.h"
  38. #include "ScriptBind_VehicleSystem.h"
  39. #include "FlashUI/ScriptBind_UIAction.h"
  40.  
  41. #include "Network/GameClientChannel.h"
  42. #include "Network/GameServerChannel.h"
  43. #include "Network/ScriptRMI.h"
  44. #include "Network/GameQueryListener.h"
  45. #include "Network/GameContext.h"
  46. #include "Network/GameServerNub.h"
  47. #include "Network/NetworkCVars.h"
  48. #include "Network/GameStatsConfig.h"
  49. #include "Network/NetworkStallTicker.h"
  50.  
  51. #include "AI/AIProxyManager.h"
  52. #include "AI/BehaviorTreeNodes_Action.h"
  53. #include <CryAISystem/ICommunicationManager.h>
  54. #include <CryAISystem/IFactionMap.h>
  55. #include <CryAISystem/ISelectionTreeManager.h>
  56. #include <CryAISystem/BehaviorTree/IBehaviorTree.h>
  57. #include <CryAISystem/INavigationSystem.h>
  58. #include <CrySandbox/IEditorGame.h>
  59. #include <CrySystem/Profilers/IStatoscope.h>
  60. #include <CrySystem/IStreamEngine.h>
  61. #include <Cry3DEngine/ITimeOfDay.h>
  62. #include <CryGame/IGameStartup.h>
  63.  
  64. #include <CrySystem/IProjectManager.h>
  65.  
  66. #include "Serialization/GameSerialize.h"
  67.  
  68. #include "Mannequin/AnimationDatabaseManager.h"
  69.  
  70. #include "DevMode.h"
  71. #include "ActionGame.h"
  72.  
  73. #include "AIHandler.h"
  74. #include "AIProxy.h"
  75.  
  76. #include "CryActionCVars.h"
  77.  
  78. // game object extensions
  79. #include "Inventory.h"
  80.  
  81. #include "FlowSystem/FlowSystem.h"
  82. #include "FlowSystem/Modules/ModuleManager.h"
  83. #include "IVehicleSystem.h"
  84. #include "GameTokens/GameTokenSystem.h"
  85. #include "EffectSystem/EffectSystem.h"
  86. #include "VehicleSystem/ScriptBind_Vehicle.h"
  87. #include "VehicleSystem/ScriptBind_VehicleSeat.h"
  88. #include "VehicleSystem/Vehicle.h"
  89. #include "AnimationGraph/AnimatedCharacter.h"
  90. #include "AnimationGraph/AnimationGraphCVars.h"
  91. #include "MaterialEffects/MaterialEffects.h"
  92. #include "MaterialEffects/MaterialEffectsCVars.h"
  93. #include "MaterialEffects/ScriptBind_MaterialEffects.h"
  94. #include "GameObjects/GameObjectSystem.h"
  95. #include "ViewSystem/ViewSystem.h"
  96. #include "GameplayRecorder/GameplayRecorder.h"
  97. #include "Analyst.h"
  98. #include "BreakableGlassSystem.h"
  99.  
  100. #include "ForceFeedbackSystem/ForceFeedbackSystem.h"
  101.  
  102. #include "Network/GameClientNub.h"
  103.  
  104. #include "DialogSystem/DialogSystem.h"
  105. #include "DialogSystem/ScriptBind_DialogSystem.h"
  106. #include "SubtitleManager.h"
  107.  
  108. #include "LevelSystem.h"
  109. #include "ActorSystem.h"
  110. #include "ItemSystem.h"
  111. #include "VehicleSystem.h"
  112. #include "SharedParams/SharedParamsManager.h"
  113. #include "ActionMapManager.h"
  114. #include "ColorGradientManager.h"
  115.  
  116. #include "Statistics/GameStatistics.h"
  117. #include "UIDraw/UIDraw.h"
  118. #include "GameRulesSystem.h"
  119. #include "ActionGame.h"
  120. #include "IGameObject.h"
  121. #include "CallbackTimer.h"
  122. #include "PersistantDebug.h"
  123. #include <CrySystem/ITextModeConsole.h>
  124. #include "TimeOfDayScheduler.h"
  125. #include "CooperativeAnimationManager/CooperativeAnimationManager.h"
  126. #include "Network/CVarListProcessor.h"
  127. #include "Network/BreakReplicator.h"
  128. #include "CheckPoint/CheckPointSystem.h"
  129. #include "GameSession/GameSessionHandler.h"
  130.  
  131. #include "AnimationGraph/DebugHistory.h"
  132.  
  133. #include "PlayerProfiles/PlayerProfileManager.h"
  134. #include "PlayerProfiles/PlayerProfileImplFS.h"
  135. #include "PlayerProfiles/PlayerProfileImplConsole.h"
  136. #if CRY_PLATFORM_DURANGO
  137.         #include "PlayerProfiles/PlayerProfileImplDurango.h"
  138. #endif
  139. #if CRY_PLATFORM_ORBIS
  140.         #include "PlayerProfiles/PlayerProfileImplOrbis.h"
  141. #endif
  142.  
  143. #include "RemoteControl/RConServerListener.h"
  144. #include "RemoteControl/RConClientListener.h"
  145.  
  146. #include "SimpleHttpServer/SimpleHttpServerListener.h"
  147. #include "SimpleHttpServer/SimpleHttpServerWebsocketEchoListener.h"
  148.  
  149. #include "SignalTimers/SignalTimers.h"
  150. #include "RangeSignalingSystem/RangeSignaling.h"
  151.  
  152. #include "LivePreview/RealtimeRemoteUpdate.h"
  153.  
  154. #include "CustomActions/CustomActionManager.h"
  155. #include "CustomEvents/CustomEventsManager.h"
  156.  
  157. #ifdef GetUserName
  158.         #undef GetUserName
  159. #endif
  160.  
  161. #include "TestSystem/TimeDemoRecorder.h"
  162. #include <CryNetwork/INetworkService.h>
  163. #include <CryCore/Platform/IPlatformOS.h>
  164. #include <CryInput/IHardwareMouse.h>
  165.  
  166. #include "Serialization/XmlSerializeHelper.h"
  167. #include "Serialization/XMLCPBin/BinarySerializeHelper.h"
  168. #include "Serialization/XMLCPBin/Writer/XMLCPB_ZLibCompressor.h"
  169. #include "Serialization/XMLCPBin/XMLCPB_Utils.h"
  170.  
  171. #include "CryActionPhysicQueues.h"
  172.  
  173. #include "Mannequin/MannequinInterface.h"
  174.  
  175. #include "GameVolumes/GameVolumesManager.h"
  176.  
  177. #include "RuntimeAreas.h"
  178.  
  179. #include <CrySystem/Scaleform/IFlashUI.h>
  180.  
  181. #include "SegmentedWorld/SegmentedWorld.h"
  182.  
  183. #include "LipSync/LipSync_TransitionQueue.h"
  184. #include "LipSync/LipSync_FacialInstance.h"
  185.  
  186. #ifdef _LIB
  187. extern "C" IGameStartup* CreateGameStartup();
  188. #endif //_LIB
  189.  
  190. #define DEFAULT_BAN_TIMEOUT     (30.0f)
  191.  
  192. #define PROFILE_CONSOLE_NO_SAVE (0)     // For console demo's which don't save their player profile
  193.  
  194. #if PROFILE_CONSOLE_NO_SAVE
  195.         #include "PlayerProfiles/PlayerProfileImplNoSave.h"
  196. #endif
  197. #include "Network/NetMsgDispatcher.h"
  198. #include "ManualFrameStep.h"
  199.  
  200. #include <CrySystem/Profilers/FrameProfiler/FrameProfiler_JobSystem.h>
  201.  
  202. CCryAction* CCryAction::m_pThis = 0;
  203.  
  204. #define DLL_INITFUNC_SYSTEM "CreateSystemInterface"
  205.  
  206. static const int s_saveGameFrameDelay = 3; // enough to render enough frames to display the save warning icon before the save generation
  207.  
  208. static const float s_loadSaveDelay = 0.5f;  // Delay between load/save operations.
  209.  
  210. //////////////////////////////////////////////////////////////////////////
  211. struct CSystemEventListner_Action : public ISystemEventListener
  212. {
  213. public:
  214.         virtual void OnSystemEvent(ESystemEvent event, UINT_PTR wparam, UINT_PTR lparam)
  215.         {
  216.                 switch (event)
  217.                 {
  218.                 case ESYSTEM_EVENT_LEVEL_POST_UNLOAD:
  219.                         if (!gEnv->IsEditor())
  220.                         {
  221.                                 CCryAction::GetCryAction()->GetMannequinInterface().UnloadAll();
  222.                         }
  223.                         break;
  224.                 case ESYSTEM_EVENT_3D_POST_RENDERING_END:
  225.                         {
  226.                                 if (IMaterialEffects* pMaterialEffects = CCryAction::GetCryAction()->GetIMaterialEffects())
  227.                                 {
  228.                                         pMaterialEffects->Reset(true);
  229.                                 }
  230.                                 break;
  231.                         }
  232.                 case ESYSTEM_EVENT_FAST_SHUTDOWN:
  233.                         {
  234.                                 CCryAction::GetCryAction()->ShutdownEngineFast();
  235.                         }
  236.                         break;
  237.                 }
  238.         }
  239. };
  240. static CSystemEventListner_Action g_system_event_listener_action;
  241.  
  242. void CCryAction::DumpMemInfo(const char* format, ...)
  243. {
  244.         CryModuleMemoryInfo memInfo;
  245.         CryGetMemoryInfoForModule(&memInfo);
  246.  
  247.         va_list args;
  248.         va_start(args, format);
  249.         gEnv->pLog->LogV(ILog::eAlways, format, args);
  250.         va_end(args);
  251.  
  252.         gEnv->pLog->LogWithType(ILog::eAlways, "Alloc=%" PRIu64 "d kb  String=%" PRIu64 " kb  STL-alloc=%" PRIu64 " kb  STL-wasted=%" PRIu64 " kb", (memInfo.allocated - memInfo.freed) >> 10, memInfo.CryString_allocated >> 10, memInfo.STL_allocated >> 10, memInfo.STL_wasted >> 10);
  253. }
  254.  
  255. // no dot use iterators in first part because of calls of some listners may modify array of listeners (add new)
  256. #define CALL_FRAMEWORK_LISTENERS(func)                                  \
  257.   {                                                                     \
  258.     for (size_t n = 0; n < m_pGFListeners->size(); n++)                 \
  259.     {                                                                   \
  260.       const SGameFrameworkListener& le = m_pGFListeners->operator[](n); \
  261.       if (m_validListeners[n])                                          \
  262.         le.pListener->func;                                             \
  263.     }                                                                   \
  264.     TGameFrameworkListeners::iterator it = m_pGFListeners->begin();     \
  265.     std::vector<bool>::iterator vit = m_validListeners.begin();         \
  266.     while (it != m_pGFListeners->end())                                 \
  267.     {                                                                   \
  268.       if (!*vit)                                                        \
  269.       {                                                                 \
  270.         it = m_pGFListeners->erase(it);                                 \
  271.         vit = m_validListeners.erase(vit);                              \
  272.       }                                                                 \
  273.       else                                                              \
  274.         ++it, ++vit;                                                    \
  275.     }                                                                   \
  276.   }
  277.  
  278. //------------------------------------------------------------------------
  279. CCryAction::CCryAction()
  280.         : m_paused(false),
  281.         m_forcedpause(false),
  282.         m_pSystem(0),
  283.         m_pNetwork(0),
  284.         m_p3DEngine(0),
  285.         m_pScriptSystem(0),
  286.         m_pEntitySystem(0),
  287.         m_pTimer(0),
  288.         m_pLog(0),
  289.         m_systemDll(0),
  290.         m_pGame(0),
  291.         m_pLevelSystem(0),
  292.         m_pActorSystem(0),
  293.         m_pItemSystem(0),
  294.         m_pVehicleSystem(0),
  295.         m_pSharedParamsManager(0),
  296.         m_pActionMapManager(0),
  297.         m_pViewSystem(0),
  298.         m_pGameplayRecorder(0),
  299.         m_pGameplayAnalyst(0),
  300.         m_pGameRulesSystem(0),
  301.         m_pFlowSystem(0),
  302.         m_pGameObjectSystem(0),
  303.         m_pScriptRMI(0),
  304.         m_pUIDraw(0),
  305.         m_pAnimationGraphCvars(0),
  306.         m_pMannequin(0),
  307.         m_pMaterialEffects(0),
  308.         m_pBreakableGlassSystem(0),
  309.         m_pForceFeedBackSystem(0),
  310.         m_pPlayerProfileManager(0),
  311.         m_pDialogSystem(0),
  312.         m_pSubtitleManager(0),
  313.         m_pGameTokenSystem(0),
  314.         m_pEffectSystem(0),
  315.         m_pGameSerialize(0),
  316.         m_pCallbackTimer(0),
  317.         m_pLanQueryListener(0),
  318.         m_pDevMode(0),
  319.         m_pTimeDemoRecorder(0),
  320.         m_pGameQueryListener(0),
  321.         m_pRuntimeAreaManager(NULL),
  322.         m_pScriptA(0),
  323.         m_pScriptIS(0),
  324.         m_pScriptAS(0),
  325.         m_pScriptNet(0),
  326.         m_pScriptAMM(0),
  327.         m_pScriptVS(0),
  328.         m_pScriptBindVehicle(0),
  329.         m_pScriptBindVehicleSeat(0),
  330.         m_pScriptInventory(0),
  331.         m_pScriptBindDS(0),
  332.         m_pScriptBindMFX(0),
  333.         m_pScriptBindUIAction(0),
  334.         m_pPersistantDebug(0),
  335.         m_pColorGradientManager(nullptr),
  336.         m_pMaterialEffectsCVars(0),
  337.         m_pEnableLoadingScreen(0),
  338.         m_pShowLanBrowserCVAR(0),
  339.         m_pDebugSignalTimers(0),
  340.         m_pAsyncLevelLoad(0),
  341.         m_pDebugRangeSignaling(0),
  342.         m_bShowLanBrowser(false),
  343.         m_isEditing(false),
  344.         m_bScheduleLevelEnd(false),
  345.         m_delayedSaveGameMethod(eSGM_NoSave),
  346.         m_delayedSaveCountDown(0),
  347.         m_pLocalAllocs(0),
  348.         m_bAllowSave(true),
  349.         m_bAllowLoad(true),
  350.         m_pGFListeners(0),
  351.         m_pBreakEventListener(NULL),
  352.         m_nextFrameCommand(0),
  353.         m_lastSaveLoad(0.0f),
  354.         m_lastFrameTimeUI(0.0f),
  355.         m_pbSvEnabled(false),
  356.         m_pbClEnabled(false),
  357.         m_pGameStatistics(0),
  358.         m_pAIDebugRenderer(0),
  359.         m_pAINetworkDebugRenderer(0),
  360.         m_pCooperativeAnimationManager(NULL),
  361.         m_pGameSessionHandler(0),
  362.         m_pAIProxyManager(0),
  363.         m_pSegmentedWorld(0),
  364.         m_pCustomActionManager(0),
  365.         m_pCustomEventManager(0),
  366.         m_pPhysicsQueues(0),
  367.         m_PreUpdateTicks(0),
  368.         m_pGameVolumesManager(NULL),
  369.         m_pNetMsgDispatcher(0),
  370.         m_pManualFrameStepController(nullptr)
  371. {
  372.         CRY_ASSERT(!m_pThis);
  373.         m_pThis = this;
  374.  
  375.         m_editorLevelName[0] = 0;
  376.         m_editorLevelFolder[0] = 0;
  377.         cry_strcpy(m_gameGUID, "{00000000-0000-0000-0000-000000000000}");
  378. }
  379.  
  380. #if 0
  381. // TODO: REMOVE: Temporary for testing (Craig)
  382. void CCryAction::FlowTest(IConsoleCmdArgs* args)
  383. {
  384.         IFlowGraphPtr pFlowGraph = GetCryAction()->m_pFlowSystem->CreateFlowGraph();
  385.         pFlowGraph->SerializeXML(::GetISystem()->LoadXmlFromFile("Libs/FlowNodes/testflow.xml"), true);
  386.         GetCryAction()->m_pFlowSystem->SetActiveFlowGraph(pFlowGraph);
  387. }
  388. #endif
  389.  
  390. //------------------------------------------------------------------------
  391. void CCryAction::DumpMapsCmd(IConsoleCmdArgs* args)
  392. {
  393.         int nlevels = GetCryAction()->GetILevelSystem()->GetLevelCount();
  394.         if (!nlevels)
  395.                 CryLogAlways("$3No levels found!");
  396.         else
  397.                 CryLogAlways("$3Found %d levels:", nlevels);
  398.  
  399.         for (int i = 0; i < nlevels; i++)
  400.         {
  401.                 ILevelInfo* level = GetCryAction()->GetILevelSystem()->GetLevelInfo(i);
  402.                 const uint32 scanTag = level->GetScanTag();
  403.                 const uint32 levelTag = level->GetLevelTag();
  404.  
  405.                 CryLogAlways("  %s [$9%s$o] Scan:%.4s Level:%.4s", level->GetName(), level->GetPath(), (char*)&scanTag, (char*)&levelTag);
  406.         }
  407. }
  408. //------------------------------------------------------------------------
  409.  
  410. void CCryAction::ReloadReadabilityXML(IConsoleCmdArgs*)
  411. {
  412.         CAIFaceManager::LoadStatic();
  413. }
  414.  
  415. //------------------------------------------------------------------------
  416. void CCryAction::UnloadCmd(IConsoleCmdArgs* args)
  417. {
  418.         if (gEnv->IsEditor())
  419.         {
  420.                 GameWarning("Won't unload level in editor");
  421.                 return;
  422.         }
  423.  
  424.         CCryAction* pAction = CCryAction::GetCryAction();
  425.         pAction->StartNetworkStallTicker(false);
  426.         // Free context
  427.         pAction->EndGameContext();
  428.         pAction->StopNetworkStallTicker();
  429. }
  430.  
  431. //------------------------------------------------------------------------
  432. void CCryAction::StaticSetPbSvEnabled(IConsoleCmdArgs* pArgs)
  433. {
  434.         if (!m_pThis)
  435.                 return;
  436.  
  437.         if (pArgs->GetArgCount() != 2)
  438.                 GameWarning("usage: net_pb_sv_enable <true|false>");
  439.         else
  440.         {
  441.                 string cond = pArgs->GetArg(1);
  442.                 if (cond == "true")
  443.                         m_pThis->m_pbSvEnabled = true;
  444.                 else if (cond == "false")
  445.                         m_pThis->m_pbSvEnabled = false;
  446.         }
  447.  
  448.         GameWarning("PunkBuster server will be %s for the next MP session", m_pThis->m_pbSvEnabled ? "enabled" : "disabled");
  449. }
  450.  
  451. //------------------------------------------------------------------------
  452. void CCryAction::StaticSetPbClEnabled(IConsoleCmdArgs* pArgs)
  453. {
  454.         if (pArgs->GetArgCount() != 2)
  455.                 GameWarning("usage: net_pb_cl_enable <true|false>");
  456.         else
  457.         {
  458.                 string cond = pArgs->GetArg(1);
  459.                 if (cond == "true")
  460.                         m_pThis->m_pbClEnabled = true;
  461.                 else if (cond == "false")
  462.                         m_pThis->m_pbClEnabled = false;
  463.         }
  464.  
  465.         GameWarning("PunkBuster client will be %s for the next MP session", m_pThis->m_pbClEnabled ? "enabled" : "disabled");
  466. }
  467.  
  468. uint16 ChooseListenPort()
  469. {
  470.         return (gEnv->pLobby && gEnv->bMultiplayer) ?
  471.                gEnv->pLobby->GetLobbyParameters().m_listenPort :
  472.                gEnv->pConsole->GetCVar("sv_port")->GetIVal();
  473. }
  474.  
  475. //------------------------------------------------------------------------
  476. void CCryAction::MapCmd(IConsoleCmdArgs* args)
  477. {
  478.         SLICE_SCOPE_DEFINE();
  479.  
  480.         LOADING_TIME_PROFILE_SECTION;
  481.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "MapCmd");
  482.  
  483.         uint32 flags = eGSF_NonBlockingConnect;
  484.  
  485.         // not available in the editor
  486.         if (gEnv->IsEditor())
  487.         {
  488.                 GameWarning("Won't load level in editor");
  489.                 return;
  490.         }
  491.  
  492.         if (GetCryAction()->StartingGameContext())
  493.         {
  494.                 GameWarning("Can't process map command while game context is starting!");
  495.                 return;
  496.         }
  497.  
  498.         class CParamCheck
  499.         {
  500.         public:
  501.                 void          AddParam(const string& param) { m_commands.insert(param); }
  502.                 const string* GetFullParam(const string& shortParam)
  503.                 {
  504.                         m_temp = m_commands;
  505.  
  506.                         for (string::const_iterator pChar = shortParam.begin(); pChar != shortParam.end(); ++pChar)
  507.                         {
  508.                                 typedef std::set<string>::iterator I;
  509.                                 I next;
  510.                                 for (I iter = m_temp.begin(); iter != m_temp.end(); )
  511.                                 {
  512.                                         next = iter;
  513.                                         ++next;
  514.                                         if ((*iter)[pChar - shortParam.begin()] != *pChar)
  515.                                                 m_temp.erase(iter);
  516.                                         iter = next;
  517.                                 }
  518.                         }
  519.  
  520.                         const char* warning = 0;
  521.                         const string* ret = 0;
  522.                         switch (m_temp.size())
  523.                         {
  524.                         case 0:
  525.                                 warning = "Unknown command %s";
  526.                                 break;
  527.                         case 1:
  528.                                 ret = &*m_temp.begin();
  529.                                 break;
  530.                         default:
  531.                                 warning = "Ambiguous command %s";
  532.                                 break;
  533.                         }
  534.                         if (warning)
  535.                                 GameWarning(warning, shortParam.c_str());
  536.  
  537.                         return ret;
  538.                 }
  539.  
  540.         private:
  541.                 std::set<string> m_commands;
  542.                 std::set<string> m_temp;
  543.         };
  544.  
  545.         IConsole* pConsole = gEnv->pConsole;
  546.  
  547.         CryStackStringT<char, 256> currentMapName;
  548.         {
  549.                 string mapname;
  550.  
  551.                 // check if a map name was provided
  552.                 if (args->GetArgCount() > 1)
  553.                 {
  554.                         // set sv_map
  555.                         mapname = args->GetArg(1);
  556.                         mapname.replace("\\", "/");
  557.  
  558.                         if (mapname.find("/") == string::npos)
  559.                         {
  560.                                 const char* gamerules = pConsole->GetCVar("sv_gamerules")->GetString();
  561.  
  562.                                 int i = 0;
  563.                                 const char* loc = 0;
  564.                                 string tmp;
  565.                                 while (loc = CCryAction::GetCryAction()->m_pGameRulesSystem->GetGameRulesLevelLocation(gamerules, i++))
  566.                                 {
  567.                                         tmp = loc;
  568.                                         tmp.append(mapname);
  569.  
  570.                                         if (CCryAction::GetCryAction()->m_pLevelSystem->GetLevelInfo(tmp.c_str()))
  571.                                         {
  572.                                                 mapname = tmp;
  573.                                                 break;
  574.                                         }
  575.                                 }
  576.                         }
  577.  
  578.                         pConsole->GetCVar("sv_map")->Set(mapname);
  579.  
  580.                         currentMapName = mapname;
  581.                 }
  582.         }
  583.  
  584.         const char* tempGameRules = pConsole->GetCVar("sv_gamerules")->GetString();
  585.  
  586.         if (const char* correctGameRules = CCryAction::GetCryAction()->m_pGameRulesSystem->GetGameRulesName(tempGameRules))
  587.                 tempGameRules = correctGameRules;
  588.  
  589.         const char* tempLevel = pConsole->GetCVar("sv_map")->GetString();
  590.         string tempDemoFile;
  591.  
  592.         ILevelInfo* pLevelInfo = CCryAction::GetCryAction()->m_pLevelSystem->GetLevelInfo(tempLevel);
  593.         if (!pLevelInfo)
  594.         {
  595.                 GameWarning("Couldn't find map '%s'", tempLevel);
  596.                 gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_ERROR, 0, 0);
  597.                 return;
  598.         }
  599.         else
  600.         {
  601. #if defined(IS_COMMERCIAL)
  602.                 string levelpak = pLevelInfo->GetPath() + string("/level.pak");
  603.                 if (!gEnv->pCryPak->OpenPack(levelpak, (unsigned)0))
  604.                 {
  605.                         GameWarning("Can't open PAK files for this level");
  606.                         gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_ERROR, 0, 0);
  607.                         return;
  608.                 }
  609.  
  610.                 bool bEncrypted = false;
  611.                 bool bHasError = false;
  612.  
  613.                 // force decryption for commercial freeSDK in launcher, editor can open non-encrypted files
  614.                 CHECK_ENCRYTPED_COMMERCIAL_LEVEL_PAK(pLevelInfo->GetPath(), bEncrypted, bHasError);
  615.  
  616.                 if ((!bEncrypted || bHasError) && !gEnv->IsEditor())
  617.                 {
  618.                         gEnv->pCryPak->ClosePack(levelpak, (unsigned)0);
  619.                         char dName[256] = { 0, };
  620.                         GameWarning("This version of CRYENGINE is licensed to %s and cannot open unencrypted levels", gEnv->pSystem->GetDeveloperName(dName));
  621.                         gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_ERROR, 0, 0);
  622.                         return;
  623.                 }
  624.                 gEnv->pCryPak->ClosePack(levelpak, (unsigned)0);
  625. #endif
  626.  
  627.                 // If the level doesn't support the current game rules then use the level's default game rules
  628.                 if (!pLevelInfo->SupportsGameType(tempGameRules))
  629.                 {
  630.                         if ((gEnv->bMultiplayer == true) || (stricmp(tempGameRules, "SinglePlayer") != 0))
  631.                         {
  632.                                 const char* sDefaultGameRules = pLevelInfo->GetDefaultGameRules();
  633.                                 if (sDefaultGameRules)
  634.                                 {
  635.                                         tempGameRules = sDefaultGameRules;
  636.                                 }
  637.                         }
  638.                 }
  639.         }
  640.  
  641.         CryLogAlways("============================ Loading level %s ============================", currentMapName.c_str());
  642.         gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_PREPARE, 0, 0);
  643.  
  644.         SGameContextParams ctx;
  645.         ctx.gameRules = tempGameRules;
  646.         ctx.levelName = tempLevel;
  647.  
  648.         // check if we want to run a dedicated server
  649.         bool dedicated = false;
  650.         bool server = false;
  651.         bool forceNewContext = false;
  652.  
  653.         //if running dedicated network server - default nonblocking mode
  654.         bool blocking = true;
  655.         if (GetCryAction()->StartedGameContext())
  656.         {
  657.                 blocking = !::gEnv->IsDedicated();
  658.         }
  659.         //
  660.         ICVar* pImmersive = gEnv->pConsole->GetCVar("g_immersive");
  661.         if (pImmersive && pImmersive->GetIVal() != 0)
  662.         {
  663.                 flags |= eGSF_ImmersiveMultiplayer;
  664.         }
  665.         //
  666.         if (args->GetArgCount() > 2)
  667.         {
  668.                 CParamCheck paramCheck;
  669.                 paramCheck.AddParam("dedicated");
  670.                 paramCheck.AddParam("record");
  671.                 paramCheck.AddParam("server");
  672.                 paramCheck.AddParam("nonblocking"); //If this is set, map load and player connection become non-blocking operations.
  673.                 paramCheck.AddParam("nb");          //This flag previously made initial server connection non-blocking. This is now always enabled.
  674.                 paramCheck.AddParam("x");
  675.                 //
  676.                 for (int i = 2; i < args->GetArgCount(); i++)
  677.                 {
  678.                         string param(args->GetArg(i));
  679.                         const string* pArg = paramCheck.GetFullParam(param);
  680.                         if (!pArg)
  681.                                 return;
  682.                         const char* arg = pArg->c_str();
  683.  
  684.                         // if 'd' or 'dedicated' is specified as a second argument we are server only
  685.                         if (!strcmp(arg, "dedicated") || !strcmp(arg, "d"))
  686.                         {
  687.                                 dedicated = true;
  688.                                 blocking = false;
  689.                         }
  690.                         else if (!strcmp(arg, "record"))
  691.                         {
  692.                                 int j = i + 1;
  693.                                 if (j >= args->GetArgCount())
  694.                                         continue;
  695.                                 tempDemoFile = args->GetArg(j);
  696.                                 i = j;
  697.  
  698.                                 ctx.demoRecorderFilename = tempDemoFile.c_str();
  699.  
  700.                                 flags |= eGSF_DemoRecorder;
  701.                                 server = true; // otherwise we will not be able to create more than one GameChannel when starting DemoRecorder
  702.                         }
  703.                         else if (!strcmp(arg, "server"))
  704.                         {
  705.                                 server = true;
  706.                         }
  707.                         else if (!strcmp(arg, "nonblocking"))
  708.                         {
  709.                                 blocking = false;
  710.                         }
  711.                         else if (!strcmp(arg, "nb"))
  712.                         {
  713.                                 //This is always on now - check is preserved for backwards compatibility
  714.                         }
  715.                         else if (!strcmp(arg, "x"))
  716.                         {
  717.                                 flags |= eGSF_ImmersiveMultiplayer;
  718.                         }
  719.                         else
  720.                         {
  721.                                 GameWarning("Added parameter %s to paramCheck, but no action performed", arg);
  722.                                 gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_LEVEL_LOAD_ERROR, 0, 0);
  723.                                 return;
  724.                         }
  725.                 }
  726.         }
  727.  
  728. #ifndef _RELEASE
  729.         gEnv->pSystem->SetLoadOrigin(ISystem::eLLO_MapCmd);
  730. #endif
  731.  
  732.         if (blocking)
  733.         {
  734.                 flags |= eGSF_BlockingClientConnect | /*eGSF_LocalOnly | eGSF_NoQueries |*/ eGSF_BlockingMapLoad;
  735.                 forceNewContext = true;
  736.         }
  737.  
  738.         const ICVar* pAsyncLoad = gEnv->pConsole->GetCVar("g_asynclevelload");
  739.         const bool bAsyncLoad = pAsyncLoad && pAsyncLoad->GetIVal() > 0;
  740.         if (bAsyncLoad)
  741.         {
  742.                 flags |= eGSF_NonBlockingConnect;
  743.         }
  744.  
  745.         if (::gEnv->IsDedicated())
  746.                 dedicated = true;
  747.  
  748.         if (dedicated || stricmp(ctx.gameRules, "SinglePlayer") != 0)
  749.         {
  750.                 //              tempLevel = "Multiplayer/" + tempLevel;
  751.                 //              ctx.levelName = tempLevel.c_str();
  752.                 server = true;
  753.         }
  754.  
  755.         bool startedContext = false;
  756.         // if we already have a game context, then we just change it
  757.         if (GetCryAction()->StartedGameContext())
  758.         {
  759.                 if (forceNewContext)
  760.                         GetCryAction()->EndGameContext();
  761.                 else
  762.                 {
  763.                         GetCryAction()->ChangeGameContext(&ctx);
  764.                         startedContext = true;
  765.                 }
  766.         }
  767.  
  768.         if (CCryAction::GetCryAction()->GetIGameSessionHandler() &&
  769.             !CCryAction::GetCryAction()->GetIGameSessionHandler()->ShouldCallMapCommand(tempLevel, tempGameRules))
  770.         {
  771.                 return;
  772.         }
  773.  
  774.         if (ctx.levelName)
  775.         {
  776.                 CCryAction::GetCryAction()->GetILevelSystem()->PrepareNextLevel(ctx.levelName);
  777.         }
  778.  
  779.         CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_mapCmdIssued, 0, currentMapName));
  780.  
  781.         if (!startedContext)
  782.         {
  783.                 CRY_ASSERT(!GetCryAction()->StartedGameContext());
  784.  
  785.                 SGameStartParams params;
  786.                 params.flags = flags | eGSF_Server;
  787.  
  788.                 if (!dedicated)
  789.                 {
  790.                         params.flags |= eGSF_Client;
  791.                         params.hostname = "localhost";
  792.                 }
  793.                 if (server)
  794.                 {
  795.                         ICVar* max_players = gEnv->pConsole->GetCVar("sv_maxplayers");
  796.                         params.maxPlayers = max_players ? max_players->GetIVal() : 16;
  797.                         ICVar* loading = gEnv->pConsole->GetCVar("g_enableloadingscreen");
  798.                         if (loading)
  799.                                 loading->Set(0);
  800.                         //gEnv->pConsole->GetCVar("g_enableitems")->Set(0);
  801.                 }
  802.                 else
  803.                 {
  804.                         params.flags |= eGSF_LocalOnly;
  805.                         params.maxPlayers = 1;
  806.                 }
  807.  
  808.                 params.pContextParams = &ctx;
  809.                 params.port = ChooseListenPort();
  810.                 params.session = CCryAction::GetCryAction()->GetIGameSessionHandler()->GetGameSessionHandle();
  811.  
  812.                 if (!CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules())
  813.                 {
  814.                         params.flags |= (eGSF_NoSpawnPlayer | eGSF_NoGameRules);
  815.                 }
  816.  
  817.                 CCryAction::GetCryAction()->StartGameContext(&params);
  818.         }
  819. }
  820.  
  821. //------------------------------------------------------------------------
  822. void CCryAction::PlayCmd(IConsoleCmdArgs* args)
  823. {
  824.         IConsole* pConsole = gEnv->pConsole;
  825.  
  826.         if (GetCryAction()->StartedGameContext())
  827.         {
  828.                 GameWarning("Must stop the game before commencing playback");
  829.                 return;
  830.         }
  831.         if (args->GetArgCount() < 2)
  832.         {
  833.                 GameWarning("Usage: \\play demofile");
  834.                 return;
  835.         }
  836.  
  837.         SGameStartParams params;
  838.         SGameContextParams context;
  839.  
  840.         params.pContextParams = &context;
  841.         context.demoPlaybackFilename = args->GetArg(1);
  842.         params.maxPlayers = 1;
  843.         params.flags = eGSF_Client | eGSF_Server | eGSF_DemoPlayback | eGSF_NoGameRules | eGSF_NoLevelLoading;
  844.         params.port = ChooseListenPort();
  845.         GetCryAction()->StartGameContext(&params);
  846. }
  847.  
  848. //------------------------------------------------------------------------
  849. void CCryAction::ConnectCmd(IConsoleCmdArgs* args)
  850. {
  851.         if (!gEnv->bServer)
  852.         {
  853.                 if (INetChannel* pCh = GetCryAction()->GetClientChannel())
  854.                         pCh->Disconnect(eDC_UserRequested, "User left the game");
  855.         }
  856.         GetCryAction()->EndGameContext();
  857.  
  858.         IConsole* pConsole = gEnv->pConsole;
  859.  
  860.         // check if a server address was provided
  861.         if (args->GetArgCount() > 1)
  862.         {
  863.                 // set cl_serveraddr
  864.                 pConsole->GetCVar("cl_serveraddr")->Set(args->GetArg(1));
  865.         }
  866.  
  867.         // check if a port was provided
  868.         if (args->GetArgCount() > 2)
  869.         {
  870.                 // set cl_serverport
  871.                 pConsole->GetCVar("cl_serverport")->Set(args->GetArg(2));
  872.         }
  873.  
  874.         string tempHost = pConsole->GetCVar("cl_serveraddr")->GetString();
  875.  
  876.         // If <session> isn't specified in the command, try to join the first searchable
  877.         // hosted session at the address specified in cl_serveraddr
  878.         if (tempHost.find("<session>") == tempHost.npos)
  879.         {
  880.                 ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  881.                 if (pMatchMaking)
  882.                 {
  883.                         CrySessionID session = pMatchMaking->GetSessionIDFromConsole();
  884.                         if (session != CrySessionInvalidID)
  885.                         {
  886.                                 GetCryAction()->GetIGameSessionHandler()->JoinSessionFromConsole(session);
  887.                                 return;
  888.                         }
  889.                 }
  890.         }
  891.  
  892.         SGameStartParams params;
  893.         params.flags = eGSF_Client /*| eGSF_BlockingClientConnect*/;
  894.         params.flags |= eGSF_ImmersiveMultiplayer;
  895.         params.hostname = tempHost.c_str();
  896.         params.pContextParams = NULL;
  897.         params.port = (gEnv->pLobby && gEnv->bMultiplayer) ? gEnv->pLobby->GetLobbyParameters().m_connectPort : pConsole->GetCVar("cl_serverport")->GetIVal();
  898.         GetCryAction()->StartGameContext(&params);
  899. }
  900.  
  901. //------------------------------------------------------------------------
  902. void CCryAction::DisconnectCmd(IConsoleCmdArgs* args)
  903. {
  904.         if (gEnv->IsEditor())
  905.                 return;
  906.  
  907.         CCryAction* pCryAction = GetCryAction();
  908.  
  909.         pCryAction->GetIGameSessionHandler()->OnUserQuit();
  910.  
  911.         if (!gEnv->bServer)
  912.         {
  913.                 if (INetChannel* pCh = pCryAction->GetClientChannel())
  914.                         pCh->Disconnect(eDC_UserRequested, "User left the game");
  915.         }
  916.  
  917.         pCryAction->StartNetworkStallTicker(false);
  918.         pCryAction->EndGameContext();
  919.         pCryAction->StopNetworkStallTicker();
  920.  
  921.         CCryAction::GetCryAction()->OnActionEvent(SActionEvent(eAE_disconnectCommandFinished, 0, "Disconnect Command Done"));
  922. }
  923.  
  924. //------------------------------------------------------------------------
  925. void CCryAction::DisconnectChannelCmd(IConsoleCmdArgs* args)
  926. {
  927.         CCryAction* pCryAction = GetCryAction();
  928.  
  929.         if (!gEnv->bServer)
  930.         {
  931.                 if (INetChannel* pCh = pCryAction->GetClientChannel())
  932.                         pCh->Disconnect(eDC_UserRequested, "User left the game");
  933.         }
  934. }
  935.  
  936. //------------------------------------------------------------------------
  937. void CCryAction::VersionCmd(IConsoleCmdArgs* args)
  938. {
  939.         CryLogAlways("-----------------------------------------");
  940.         char myVersion[PRODUCT_VERSION_MAX_STRING_LENGTH];
  941.         gEnv->pSystem->GetProductVersion().ToString(myVersion);
  942.         CryLogAlways("Product version: %s", myVersion);
  943.         gEnv->pSystem->GetFileVersion().ToString(myVersion);
  944.         CryLogAlways("File version: %s", myVersion);
  945.         CryLogAlways("-----------------------------------------");
  946. }
  947.  
  948. //------------------------------------------------------------------------
  949. void CCryAction::StatusCmd(IConsoleCmdArgs* pArgs)
  950. {
  951.         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  952.  
  953.         if ((pMatchMaking != NULL) && (pArgs->GetArgCount() > 1))
  954.         {
  955.                 uint32 mode = atoi(pArgs->GetArg(1));
  956.                 pMatchMaking->StatusCmd((eStatusCmdMode)mode);
  957.         }
  958.         else
  959.         {
  960.                 LegacyStatusCmd(pArgs);
  961.         }
  962. }
  963.  
  964. void CCryAction::LegacyStatusCmd(IConsoleCmdArgs* args)
  965. {
  966.         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  967.  
  968.         CGameServerNub* pServerNub = CCryAction::GetCryAction()->GetGameServerNub();
  969.         if (!pServerNub)
  970.         {
  971.                 if (pMatchMaking != 0)
  972.                 {
  973.                         pMatchMaking->StatusCmd(eSCM_LegacyRConCompatabilityNoNub);
  974.                 }
  975.                 else
  976.                 {
  977.                         CryLogAlways("-----------------------------------------");
  978.                         CryLogAlways("Client Status:");
  979.                         CryLogAlways("name: %s", "");
  980.                         CryLogAlways("ip: %s", gEnv->pNetwork->GetHostName());
  981.                         char myVersion[PRODUCT_VERSION_MAX_STRING_LENGTH];
  982.                         gEnv->pSystem->GetProductVersion().ToString(myVersion);
  983.                         CryLogAlways("version: %s", myVersion);
  984.                         CGameClientNub* pClientNub = CCryAction::GetCryAction()->GetGameClientNub();
  985.                         if (pClientNub)
  986.                         {
  987.                                 CGameClientChannel* pClientChannel = pClientNub->GetGameClientChannel();
  988.                                 EntityId entId = pClientChannel->GetPlayerId();
  989.                                 IActor* pActor = CCryAction::GetCryAction()->m_pActorSystem->GetActor(entId);
  990.                                 const char* name = "";
  991.                                 if (pActor)
  992.                                 {
  993.                                         name = pActor->GetEntity()->GetName();
  994.                                 }
  995.                                 CryLogAlways("name: %s  entID:%d", name, entId);
  996.                         }
  997.                 }
  998.                 return;
  999.         }
  1000.  
  1001.         CryLogAlways("-----------------------------------------");
  1002.         CryLogAlways("Server Status:");
  1003.         CryLogAlways("name: %s", "");
  1004.         CryLogAlways("ip: %s", gEnv->pNetwork->GetHostName());
  1005.         char myVersion[PRODUCT_VERSION_MAX_STRING_LENGTH];
  1006.         gEnv->pSystem->GetProductVersion().ToString(myVersion);
  1007.         CryLogAlways("version: %s", myVersion);
  1008.  
  1009.         CGameContext* pGameContext = CCryAction::GetCryAction()->m_pGame->GetGameContext();
  1010.         if (!pGameContext)
  1011.                 return;
  1012.  
  1013.         CryLogAlways("level: %s", pGameContext->GetLevelName().c_str());
  1014.         CryLogAlways("gamerules: %s", pGameContext->GetRequestedGameRules().c_str());
  1015.         CryLogAlways("players: %d/%d", pServerNub->GetPlayerCount(), pServerNub->GetMaxPlayers());
  1016.  
  1017.         if (IGameRules* pRules = CCryAction::GetCryAction()->GetIGameRulesSystem()->GetCurrentGameRules())
  1018.                 pRules->ShowStatus();
  1019.  
  1020.         if (pServerNub->GetPlayerCount() < 1)
  1021.                 return;
  1022.  
  1023.         CryLogAlways("\n-----------------------------------------");
  1024.         CryLogAlways("Connection Status:");
  1025.  
  1026.         if (pMatchMaking != NULL)
  1027.         {
  1028.                 pMatchMaking->StatusCmd(eSCM_LegacyRConCompatabilityConnectionsOnly);
  1029.         }
  1030.         else
  1031.         {
  1032.                 TServerChannelMap* pChannelMap = pServerNub->GetServerChannelMap();
  1033.                 for (TServerChannelMap::iterator iter = pChannelMap->begin(); iter != pChannelMap->end(); ++iter)
  1034.                 {
  1035.                         const char* name = "";
  1036.                         IActor* pActor = CCryAction::GetCryAction()->m_pActorSystem->GetActorByChannelId(iter->first);
  1037.                         EntityId entId = 0;
  1038.  
  1039.                         if (pActor)
  1040.                         {
  1041.                                 name = pActor->GetEntity()->GetName();
  1042.                                 entId = pActor->GetEntity()->GetId();
  1043.                         }
  1044.  
  1045.                         INetChannel* pNetChannel = iter->second->GetNetChannel();
  1046.                         const char* ip = pNetChannel->GetName();
  1047.                         int ping = (int)(pNetChannel->GetPing(true) * 1000);
  1048.                         int state = pNetChannel->GetChannelConnectionState();
  1049.                         int profileId = pNetChannel->GetProfileId();
  1050.  
  1051.                         CryLogAlways("name: %s  entID:%u id: %u  ip: %s  ping: %d  state: %d profile: %d", name, entId, iter->first, ip, ping, state, profileId);
  1052.                 }
  1053.         }
  1054. }
  1055.  
  1056. //------------------------------------------------------------------------
  1057. void CCryAction::GenStringsSaveGameCmd(IConsoleCmdArgs* pArgs)
  1058. {
  1059.         CGameSerialize* cgs = GetCryAction()->m_pGameSerialize;
  1060.         if (cgs)
  1061.         {
  1062.                 cgs->SaveGame(GetCryAction(), "string-extractor", "SaveGameStrings.cpp", eSGR_Command);
  1063.         }
  1064. }
  1065.  
  1066. //------------------------------------------------------------------------
  1067. void CCryAction::SaveGameCmd(IConsoleCmdArgs* args)
  1068. {
  1069.         if (GetCryAction()->GetLevelName() != nullptr)
  1070.         {
  1071.                 string sSavePath(PathUtil::GetGameFolder());
  1072.                 if (args->GetArgCount() > 1)
  1073.                 {
  1074.                         sSavePath.append("/");
  1075.                         sSavePath.append(args->GetArg(1));
  1076.                         CryFixedStringT<64> extension(CRY_SAVEGAME_FILE_EXT);
  1077.                         extension.Trim('.');
  1078.                         sSavePath = PathUtil::ReplaceExtension(sSavePath, extension.c_str());
  1079.                         GetCryAction()->SaveGame(sSavePath, false, false, eSGR_QuickSave, true);
  1080.                 }
  1081.                 else
  1082.                 {
  1083.                         auto saveGameName = GetCryAction()->CreateSaveGameName();
  1084.  
  1085.                         GetCryAction()->SaveGame(saveGameName.c_str(), true, false);
  1086.                 }
  1087.         }
  1088.         else
  1089.         {
  1090.                 CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Cannot create save game if no level is loaded.");
  1091.         }
  1092. }
  1093.  
  1094. //------------------------------------------------------------------------
  1095. void CCryAction::LoadGameCmd(IConsoleCmdArgs* args)
  1096. {
  1097.         if (args->GetArgCount() > 1)
  1098.         {
  1099.                 GetCryAction()->NotifyForceFlashLoadingListeners();
  1100.                 bool quick = args->GetArgCount() > 2;
  1101.                 GetCryAction()->LoadGame(args->GetArg(1), quick);
  1102.         }
  1103.         else
  1104.         {
  1105.                 gEnv->pConsole->ExecuteString("loadLastSave");
  1106.         }
  1107. }
  1108.  
  1109. //------------------------------------------------------------------------
  1110. void CCryAction::KickPlayerCmd(IConsoleCmdArgs* pArgs)
  1111. {
  1112.         ICryLobby* pLobby = gEnv->pNetwork->GetLobby();
  1113.  
  1114.         if (pLobby != NULL)
  1115.         {
  1116.                 uint32 cx = ~0;
  1117.                 uint64 id = 0;
  1118.                 const char* pName = NULL;
  1119.  
  1120.                 if (pArgs->GetArgCount() > 1)
  1121.                 {
  1122.                         if (_stricmp(pArgs->GetArg(1), "cx") == 0)
  1123.                         {
  1124.                                 if (pArgs->GetArgCount() == 3)
  1125.                                 {
  1126.                                         cx = atoi(pArgs->GetArg(2));
  1127.                                 }
  1128.                         }
  1129.                         else
  1130.                         {
  1131.                                 if (_stricmp(pArgs->GetArg(1), "id") == 0)
  1132.                                 {
  1133.                                         if (pArgs->GetArgCount() == 3)
  1134.                                         {
  1135.                                                 sscanf_s(pArgs->GetArg(2), "%" PRIu64, &id);
  1136.                                         }
  1137.                                 }
  1138.                                 else
  1139.                                 {
  1140.                                         pName = pArgs->GetArg(1);
  1141.                                 }
  1142.                         }
  1143.  
  1144.                         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  1145.                         if (pMatchMaking != NULL)
  1146.                         {
  1147.                                 pMatchMaking->KickCmd(cx, id, pName, eDC_Kicked);
  1148.                         }
  1149.                 }
  1150.                 else
  1151.                 {
  1152.                         CryLogAlways("Usage: kick cx <connection id> | id <profile id> | <name>");
  1153.                         CryLogAlways("e.g.: kick cx 0, kick id 12345678, kick ElCubo - see 'status'");
  1154.                 }
  1155.  
  1156.         }
  1157.         else
  1158.         {
  1159.                 LegacyKickPlayerCmd(pArgs);
  1160.         }
  1161. }
  1162.  
  1163. void CCryAction::LegacyKickPlayerCmd(IConsoleCmdArgs* pArgs)
  1164. {
  1165.         if (!gEnv->bServer)
  1166.         {
  1167.                 CryLog("This only usable on server");
  1168.                 return;
  1169.         }
  1170.         if (pArgs->GetArgCount() > 1)
  1171.         {
  1172.                 IEntity* pEntity = gEnv->pEntitySystem->FindEntityByName(pArgs->GetArg(1));
  1173.                 if (pEntity)
  1174.                 {
  1175.                         IActor* pActor = GetCryAction()->GetIActorSystem()->GetActor(pEntity->GetId());
  1176.                         if (pActor && pActor->IsPlayer())
  1177.                         {
  1178.                                 if (pActor != GetCryAction()->GetClientActor())
  1179.                                         GetCryAction()->GetServerNetNub()->DisconnectPlayer(eDC_Kicked, pActor->GetEntityId(), "Kicked from server");
  1180.                                 else
  1181.                                         CryLog("Cannot kick local player");
  1182.                         }
  1183.                         else
  1184.                                 CryLog("%s not a player.", pArgs->GetArg(1));
  1185.                 }
  1186.                 else
  1187.                         CryLog("Player not found");
  1188.         }
  1189.         else
  1190.                 CryLog("Usage: kick player_name");
  1191. }
  1192.  
  1193. void CCryAction::KickPlayerByIdCmd(IConsoleCmdArgs* pArgs)
  1194. {
  1195.         ICryLobby* pLobby = gEnv->pNetwork->GetLobby();
  1196.  
  1197.         if (pLobby != NULL)
  1198.         {
  1199.                 if (pArgs->GetArgCount() > 1)
  1200.                 {
  1201.                         uint32 id;
  1202.                         sscanf_s(pArgs->GetArg(1), "%u", &id);
  1203.  
  1204.                         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  1205.                         if (pMatchMaking != NULL)
  1206.                         {
  1207.                                 pMatchMaking->KickCmd(id, 0, NULL, eDC_Kicked);
  1208.                         }
  1209.                 }
  1210.                 else
  1211.                 {
  1212.                         CryLog("Usage: kickid <connection id>");
  1213.                 }
  1214.         }
  1215.         else
  1216.         {
  1217.                 LegacyKickPlayerByIdCmd(pArgs);
  1218.         }
  1219. }
  1220.  
  1221. void CCryAction::LegacyKickPlayerByIdCmd(IConsoleCmdArgs* pArgs)
  1222. {
  1223.         if (!gEnv->bServer)
  1224.         {
  1225.                 CryLog("This only usable on server");
  1226.                 return;
  1227.         }
  1228.  
  1229.         if (pArgs->GetArgCount() > 1)
  1230.         {
  1231.                 int id = atoi(pArgs->GetArg(1));
  1232.  
  1233.                 CGameServerNub* pServerNub = CCryAction::GetCryAction()->GetGameServerNub();
  1234.                 if (!pServerNub)
  1235.                         return;
  1236.  
  1237.                 TServerChannelMap* pChannelMap = pServerNub->GetServerChannelMap();
  1238.                 TServerChannelMap::iterator it = pChannelMap->find(id);
  1239.                 if (it != pChannelMap->end() && (!GetCryAction()->GetClientActor() || GetCryAction()->GetClientActor() != GetCryAction()->m_pActorSystem->GetActorByChannelId(id)))
  1240.                 {
  1241.                         it->second->GetNetChannel()->Disconnect(eDC_Kicked, "Kicked from server");
  1242.                 }
  1243.                 else
  1244.                 {
  1245.                         CryLog("Player with id %d not found", id);
  1246.                 }
  1247.         }
  1248.         else
  1249.                 CryLog("Usage: kickid player_id");
  1250. }
  1251.  
  1252. void CCryAction::BanPlayerCmd(IConsoleCmdArgs* pArgs)
  1253. {
  1254.  
  1255. #if CRY_PLATFORM_WINDOWS
  1256.  
  1257.         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  1258.  
  1259.         if (pMatchMaking != NULL)
  1260.         {
  1261.                 uint64 id = 0;
  1262.                 const char* pArg;
  1263.                 char* pEnd;
  1264.                 float timeout = 0.0f;
  1265.                 bool usageError = false;
  1266.  
  1267.                 if (ICVar* pBanTimeout = gEnv->pConsole->GetCVar("ban_timeout"))
  1268.                 {
  1269.                         timeout = pBanTimeout->GetFVal();
  1270.                 }
  1271.  
  1272.                 switch (pArgs->GetArgCount())
  1273.                 {
  1274.                 case 3:
  1275.  
  1276.                         pArg = pArgs->GetArg(2);
  1277.                         timeout = static_cast<float>(strtod(pArg, &pEnd));
  1278.  
  1279.                         if ((pEnd == pArg) || *pEnd)
  1280.                         {
  1281.                                 usageError = true;
  1282.                                 break;
  1283.                         }
  1284.  
  1285.                 // FALL THROUGH
  1286.  
  1287.                 case 2:
  1288.  
  1289.                         pArg = pArgs->GetArg(1);
  1290.                         id = _strtoui64(pArg, &pEnd, 10);
  1291.  
  1292.                         if ((pEnd == pArg) || *pEnd)
  1293.                         {
  1294.                                 pMatchMaking->BanCmd(pArg, timeout);
  1295.                                 pMatchMaking->KickCmd(~0, 0, pArg, eDC_Banned);
  1296.                         }
  1297.                         else
  1298.                         {
  1299.                                 pMatchMaking->BanCmd(id, timeout);
  1300.                                 pMatchMaking->KickCmd(~0, id, pArg, eDC_Banned);  //CryLobbyInvalidConnectionID is not accessible outside CryNetwork :(
  1301.                         }
  1302.  
  1303.                         break;
  1304.  
  1305.                 default:
  1306.  
  1307.                         usageError = true;
  1308.                         break;
  1309.                 }
  1310.  
  1311.                 if (usageError)
  1312.                 {
  1313.                         CryLogAlways("Usage: ban <profile id> <minutes>");
  1314.                         CryLogAlways("       ban <user name> <minutes>");
  1315.                         CryLogAlways("e.g.: ban 12345678 30");
  1316.                 }
  1317.         }
  1318.         else
  1319.         {
  1320.                 LegacyBanPlayerCmd(pArgs);
  1321.         }
  1322.  
  1323. #endif // #if CRY_PLATFORM_WINDOWS
  1324.  
  1325. }
  1326.  
  1327. void CCryAction::LegacyBanPlayerCmd(IConsoleCmdArgs* args)
  1328. {
  1329.         if (args->GetArgCount() > 1)
  1330.         {
  1331.                 int id = atoi(args->GetArg(1));
  1332.                 CGameServerNub* pServerNub = CCryAction::GetCryAction()->GetGameServerNub();
  1333.                 if (!pServerNub)
  1334.                         return;
  1335.                 TServerChannelMap* pChannelMap = pServerNub->GetServerChannelMap();
  1336.                 for (TServerChannelMap::iterator it = pChannelMap->begin(); it != pChannelMap->end(); ++it)
  1337.                 {
  1338.                         if (it->second->GetNetChannel()->GetProfileId() == id)
  1339.                         {
  1340.                                 pServerNub->BanPlayer(it->first, "Banned from server");
  1341.                                 break;
  1342.                         }
  1343.                 }
  1344.                 CryLog("Player with profileid %d not found", id);
  1345.         }
  1346.         else
  1347.         {
  1348.                 CryLog("Usage: ban profileid");
  1349.         }
  1350. }
  1351.  
  1352. void CCryAction::BanStatusCmd(IConsoleCmdArgs* pArgs)
  1353. {
  1354.         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  1355.  
  1356.         if (pMatchMaking != NULL)
  1357.         {
  1358.                 pMatchMaking->BanStatus();
  1359.         }
  1360.         else
  1361.         {
  1362.                 LegacyBanStatusCmd(pArgs);
  1363.         }
  1364. }
  1365.  
  1366. void CCryAction::LegacyBanStatusCmd(IConsoleCmdArgs* args)
  1367. {
  1368.         if (CCryAction::GetCryAction()->GetGameServerNub())
  1369.                 CCryAction::GetCryAction()->GetGameServerNub()->BannedStatus();
  1370. }
  1371.  
  1372. void CCryAction::UnbanPlayerCmd(IConsoleCmdArgs* pArgs)
  1373. {
  1374.  
  1375. #if CRY_PLATFORM_WINDOWS
  1376.  
  1377.         ICryMatchMakingConsoleCommands* pMatchMaking = gEnv->pLobby ? gEnv->pLobby->GetMatchMakingConsoleCommands() : NULL;
  1378.  
  1379.         if (pMatchMaking != NULL)
  1380.         {
  1381.                 uint64 id = 0;
  1382.                 const char* pArg;
  1383.                 char* pEnd;
  1384.                 bool usageError = false;
  1385.  
  1386.                 switch (pArgs->GetArgCount())
  1387.                 {
  1388.                 case 2:
  1389.  
  1390.                         pArg = pArgs->GetArg(1);
  1391.                         id = _strtoui64(pArg, &pEnd, 10);
  1392.  
  1393.                         if ((pEnd == pArg) || *pEnd)
  1394.                         {
  1395.                                 pMatchMaking->UnbanCmd(pArg);
  1396.                         }
  1397.                         else
  1398.                         {
  1399.                                 pMatchMaking->UnbanCmd(id);
  1400.                         }
  1401.  
  1402.                         break;
  1403.  
  1404.                 default:
  1405.  
  1406.                         usageError = true;
  1407.                         break;
  1408.                 }
  1409.  
  1410.                 if (usageError)
  1411.                 {
  1412.                         CryLogAlways("Usage: ban_remove <profile id>");
  1413.                         CryLogAlways("       ban_remove <user name>");
  1414.                         CryLogAlways("e.g.: ban_remove 12345678");
  1415.                 }
  1416.         }
  1417.         else
  1418.         {
  1419.                 LegacyUnbanPlayerCmd(pArgs);
  1420.         }
  1421.  
  1422. #endif // #if CRY_PLATFORM_WINDOWS
  1423. }
  1424.  
  1425. void CCryAction::LegacyUnbanPlayerCmd(IConsoleCmdArgs* args)
  1426. {
  1427.         if (args->GetArgCount() > 1)
  1428.         {
  1429.                 int id = atoi(args->GetArg(1));
  1430.                 CGameServerNub* pServerNub = CCryAction::GetCryAction()->GetGameServerNub();
  1431.                 if (!pServerNub)
  1432.                         return;
  1433.                 pServerNub->UnbanPlayer(id);
  1434.         }
  1435.         else
  1436.         {
  1437.                 CryLog("Usage: ban_remove profileid");
  1438.         }
  1439. }
  1440.  
  1441. void CCryAction::OpenURLCmd(IConsoleCmdArgs* args)
  1442. {
  1443.         if (args->GetArgCount() > 1)
  1444.                 GetCryAction()->ShowPageInBrowser(args->GetArg(1));
  1445. }
  1446.  
  1447. void CCryAction::DumpAnalysisStatsCmd(IConsoleCmdArgs* args)
  1448. {
  1449.         if (CCryAction::GetCryAction()->m_pGameplayAnalyst)
  1450.                 CCryAction::GetCryAction()->m_pGameplayAnalyst->DumpToTXT();
  1451. }
  1452.  
  1453. #if !defined(_RELEASE)
  1454. void CCryAction::ConnectRepeatedlyCmd(IConsoleCmdArgs* args)
  1455. {
  1456.         ConnectCmd(args);
  1457.  
  1458.         float timeSeconds = gEnv->pTimer->GetFrameStartTime().GetSeconds();
  1459.         IConsole* pConsole = gEnv->pConsole;
  1460.  
  1461.         int numAttempts = pConsole->GetCVar("connect_repeatedly_num_attempts")->GetIVal();
  1462.         float timeBetweenAttempts = pConsole->GetCVar("connect_repeatedly_time_between_attempts")->GetFVal();
  1463.  
  1464.         GetCryAction()->m_connectRepeatedly.m_enabled = true;
  1465.         GetCryAction()->m_connectRepeatedly.m_numAttemptsLeft = numAttempts;
  1466.         GetCryAction()->m_connectRepeatedly.m_timeForNextAttempt = timeSeconds + timeBetweenAttempts;
  1467.         CryLogAlways("CCryAction::ConnectRepeatedlyCmd() numAttempts=%d; timeBetweenAttempts=%f", numAttempts, timeBetweenAttempts);
  1468. }
  1469. #endif
  1470.  
  1471. //------------------------------------------------------------------------
  1472. ISimpleHttpServer* CCryAction::s_http_server = NULL;
  1473.  
  1474. #define HTTP_DEFAULT_PORT 80
  1475.  
  1476. //------------------------------------------------------------------------
  1477. void CCryAction::http_startserver(IConsoleCmdArgs* args)
  1478. {
  1479.         if (args->GetArgCount() > 3)
  1480.         {
  1481.                 GameWarning("usage: http_startserver [port:<port>] [pass:<pass>] (no spaces or tabs allowed for individule argument)");
  1482.                 return;
  1483.         }
  1484.  
  1485.         if (s_http_server)
  1486.         {
  1487.                 GameWarning("HTTP server already started");
  1488.                 return;
  1489.         }
  1490.  
  1491.         uint16 port = HTTP_DEFAULT_PORT;
  1492.         string http_password;
  1493.         int nargs = args->GetArgCount();
  1494.         for (int i = 1; i < nargs; ++i)
  1495.         {
  1496.                 string arg(args->GetArg(i));
  1497.                 string head = arg.substr(0, 5), body = arg.substr(5);
  1498.                 if (head == "port:")
  1499.                 {
  1500.                         int pt = atoi(body);
  1501.                         if (pt <= 0 || pt > 65535)
  1502.                                 GameWarning("Invalid port specified, default port will be used");
  1503.                         else
  1504.                                 port = (uint16)pt;
  1505.                 }
  1506.                 else if (head == "pass:")
  1507.                 {
  1508.                         http_password = body;
  1509.                 }
  1510.                 else
  1511.                 {
  1512.                         GameWarning("usage: http_startserver [port:<port>] [pass:<pass>] (no spaces or tabs allowed for individule argument)");
  1513.                         return;
  1514.                 }
  1515.         }
  1516.  
  1517.         s_http_server = gEnv->pNetwork->GetSimpleHttpServerSingleton();
  1518.         s_http_server->Start(port, http_password, &CSimpleHttpServerListener::GetSingleton(s_http_server));
  1519.  
  1520. #if defined(HTTP_WEBSOCKETS)
  1521.         s_http_server->AddWebsocketProtocol("WsEcho", &CSimpleHttpServerWebsocketEchoListener::GetSingleton());
  1522. #endif
  1523. }
  1524.  
  1525. //------------------------------------------------------------------------
  1526. void CCryAction::http_stopserver(IConsoleCmdArgs* args)
  1527. {
  1528.         if (args->GetArgCount() != 1)
  1529.                 GameWarning("usage: http_stopserver (no parameters) - continue anyway ...");
  1530.  
  1531.         if (s_http_server == NULL)
  1532.         {
  1533.                 GameWarning("HTTP: server not started");
  1534.                 return;
  1535.         }
  1536.  
  1537.         s_http_server->Stop();
  1538.         s_http_server = NULL;
  1539.  
  1540.         gEnv->pLog->LogToConsole("HTTP: server stopped");
  1541. }
  1542.  
  1543. //------------------------------------------------------------------------
  1544. IRemoteControlServer* CCryAction::s_rcon_server = NULL;
  1545. IRemoteControlClient* CCryAction::s_rcon_client = NULL;
  1546.  
  1547. CRConClientListener* CCryAction::s_rcon_client_listener = NULL;
  1548.  
  1549. //string CCryAction::s_rcon_password;
  1550.  
  1551. #define RCON_DEFAULT_PORT 9999
  1552.  
  1553. //------------------------------------------------------------------------
  1554. //void CCryAction::rcon_password(IConsoleCmdArgs* args)
  1555. //{
  1556. //      if (args->GetArgCount() > 2)
  1557. //      {
  1558. //              GameWarning("usage: rcon_password [password] (password cannot contain spaces or tabs");
  1559. //              return;
  1560. //      }
  1561. //
  1562. //      if (args->GetArgCount() == 1)
  1563. //      {
  1564. //              if (s_rcon_password.empty())
  1565. //                      gEnv->pLog->LogToConsole("RCON system password has not been set");
  1566. //              else
  1567. //                      gEnv->pLog->LogToConsole("RCON system password has been set (not displayed for security reasons)");
  1568. //              return;
  1569. //      }
  1570. //
  1571. //      if (args->GetArgCount() == 2)
  1572. //      {
  1573. //              s_rcon_password = args->GetArg(1);
  1574. //      }
  1575. //}
  1576.  
  1577. //------------------------------------------------------------------------
  1578. void CCryAction::rcon_startserver(IConsoleCmdArgs* args)
  1579. {
  1580.         if (args->GetArgCount() > 3)
  1581.         {
  1582.                 GameWarning("usage: rcon_startserver [port:<port>] [pass:<pass>] (no spaces or tabs allowed for individule argument)");
  1583.                 return;
  1584.         }
  1585.  
  1586.         if (s_rcon_server)
  1587.         {
  1588.                 GameWarning("RCON server already started");
  1589.                 return;
  1590.         }
  1591.  
  1592.         uint16 port = RCON_DEFAULT_PORT;
  1593.         string rcon_password;
  1594.  
  1595.         ICVar* prcon_password = gEnv->pConsole->GetCVar("rcon_password");
  1596.         rcon_password = prcon_password->GetString();
  1597.         if (rcon_password.empty())
  1598.         {
  1599.                 // if rcon_password not set, use http_password
  1600.                 ICVar* pcvar = gEnv->pConsole->GetCVar("http_password");
  1601.                 rcon_password = pcvar->GetString();
  1602.         }
  1603.  
  1604.         int nargs = args->GetArgCount();
  1605.         for (int i = 1; i < nargs; ++i)
  1606.         {
  1607.                 string arg(args->GetArg(i));
  1608.                 string head = arg.substr(0, 5), body = arg.substr(5);
  1609.                 if (head == "port:")
  1610.                 {
  1611.                         int pt = atoi(body);
  1612.                         if (pt <= 0 || pt > 65535)
  1613.                                 GameWarning("Invalid port specified, default port will be used");
  1614.                         else
  1615.                                 port = (uint16)pt;
  1616.                 }
  1617.                 else if (head == "pass:")
  1618.                 {
  1619.                         rcon_password = body;
  1620.                         prcon_password->Set(rcon_password.c_str());
  1621.                 }
  1622.                 else
  1623.                 {
  1624.                         GameWarning("usage: rcon_startserver [port:<port>] [pass:<pass>] (no spaces or tabs allowed for individule argument)");
  1625.                         return;
  1626.                 }
  1627.         }
  1628.  
  1629.         s_rcon_server = gEnv->pNetwork->GetRemoteControlSystemSingleton()->GetServerSingleton();
  1630.         s_rcon_server->Start(port, rcon_password, &CRConServerListener::GetSingleton(s_rcon_server));
  1631. }
  1632.  
  1633. //------------------------------------------------------------------------
  1634. void CCryAction::rcon_stopserver(IConsoleCmdArgs* args)
  1635. {
  1636.         if (args->GetArgCount() != 1)
  1637.                 GameWarning("usage: rcon_stopserver (no parameters) - continue anyway ...");
  1638.  
  1639.         if (s_rcon_server == NULL)
  1640.         {
  1641.                 GameWarning("RCON: server not started");
  1642.                 return;
  1643.         }
  1644.  
  1645.         s_rcon_server->Stop();
  1646.         s_rcon_server = NULL;
  1647.         //s_rcon_password = "";
  1648.  
  1649.         gEnv->pLog->LogToConsole("RCON: server stopped");
  1650. }
  1651.  
  1652. //------------------------------------------------------------------------
  1653. void CCryAction::rcon_connect(IConsoleCmdArgs* args)
  1654. {
  1655.         if (args->GetArgCount() > 4)
  1656.         {
  1657.                 GameWarning("usage: rcon_connect [addr:<addr>] [port:<port>] [pass:<pass>]");
  1658.                 return;
  1659.         }
  1660.  
  1661.         if (s_rcon_client != NULL)
  1662.         {
  1663.                 GameWarning("RCON client already started");
  1664.                 return;
  1665.         }
  1666.  
  1667.         uint16 port = RCON_DEFAULT_PORT;
  1668.         string addr = "127.0.0.1";
  1669.         string password;
  1670.         int nargs = args->GetArgCount();
  1671.         for (int i = 1; i < nargs; ++i)
  1672.         {
  1673.                 string arg(args->GetArg(i));
  1674.                 string head = arg.substr(0, 5), body = arg.substr(5);
  1675.                 if (head == "port:")
  1676.                 {
  1677.                         int pt = atoi(body);
  1678.                         if (pt <= 0 || pt > 65535)
  1679.                                 GameWarning("Invalid port specified, default port will be used");
  1680.                         else
  1681.                                 port = (uint16)pt;
  1682.                 }
  1683.                 else if (head == "pass:")
  1684.                 {
  1685.                         password = body;
  1686.                 }
  1687.                 else if (head == "addr:")
  1688.                 {
  1689.                         addr = body;
  1690.                 }
  1691.                 else
  1692.                 {
  1693.                         GameWarning("usage: rcon_connect [addr:<addr>] [port:<port>] [pass:<pass>]");
  1694.                         return;
  1695.                 }
  1696.         }
  1697.  
  1698.         s_rcon_client = gEnv->pNetwork->GetRemoteControlSystemSingleton()->GetClientSingleton();
  1699.         s_rcon_client_listener = &CRConClientListener::GetSingleton(s_rcon_client);
  1700.         s_rcon_client->Connect(addr, port, password, s_rcon_client_listener);
  1701. }
  1702.  
  1703. //------------------------------------------------------------------------
  1704. void CCryAction::rcon_disconnect(IConsoleCmdArgs* args)
  1705. {
  1706.         if (args->GetArgCount() != 1)
  1707.                 GameWarning("usage: rcon_disconnect (no parameters) - continue anyway ...");
  1708.  
  1709.         if (s_rcon_client == NULL)
  1710.         {
  1711.                 GameWarning("RCON client not started");
  1712.                 return;
  1713.         }
  1714.  
  1715.         s_rcon_client->Disconnect();
  1716.         s_rcon_client = NULL;
  1717.         //s_rcon_password = "";
  1718.  
  1719.         gEnv->pLog->LogToConsole("RCON: client disconnected");
  1720. }
  1721.  
  1722. //------------------------------------------------------------------------
  1723. void CCryAction::rcon_command(IConsoleCmdArgs* args)
  1724. {
  1725.         if (s_rcon_client == NULL || !s_rcon_client_listener->IsSessionAuthorized())
  1726.         {
  1727.                 GameWarning("RCON: cannot issue commands unless the session is authorized");
  1728.                 return;
  1729.         }
  1730.  
  1731.         if (args->GetArgCount() < 2)
  1732.         {
  1733.                 GameWarning("usage: rcon_command [console_command arg1 arg2 ...]");
  1734.                 return;
  1735.         }
  1736.  
  1737.         string command;
  1738.         int nargs = args->GetArgCount();
  1739.         for (int i = 1; i < nargs; ++i)
  1740.         {
  1741.                 command += args->GetArg(i);
  1742.                 command += " "; // a space in between
  1743.         }
  1744.  
  1745.         uint32 cmdid = s_rcon_client->SendCommand(command);
  1746.         if (0 == cmdid)
  1747.                 GameWarning("RCON: failed sending RCON command %s to server", command.c_str());
  1748.         else
  1749.                 gEnv->pLog->LogToConsole("RCON: command [%08x]%s is sent to server for execution", cmdid, command.c_str());
  1750. }
  1751.  
  1752. #define EngineStartProfiler(x)
  1753. #define InitTerminationCheck(x)
  1754.  
  1755. static inline void InlineInitializationProcessing(const char* sDescription)
  1756. {
  1757.         EngineStartProfiler(sDescription);
  1758.         InitTerminationCheck(sDescription);
  1759.         gEnv->pLog->UpdateLoadingScreen(0);
  1760. }
  1761.  
  1762. //------------------------------------------------------------------------
  1763. bool CCryAction::StartEngine(SSystemInitParams& startupParams)
  1764. {
  1765.         MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Other, 0, "CryAction Init");
  1766.  
  1767.         m_pSystem = startupParams.pSystem;
  1768.  
  1769.         startupParams.pGameFramework = this;
  1770.  
  1771.         if (!startupParams.pSystem)
  1772.         {
  1773. #if !defined(_LIB)
  1774.                 m_systemDll = CryLoadLibraryDefName("CrySystem");
  1775.  
  1776.                 if (!m_systemDll)
  1777.                 {
  1778.                         return false;
  1779.                 }
  1780.                 PFNCREATESYSTEMINTERFACE CreateSystemInterface =
  1781.                   (PFNCREATESYSTEMINTERFACE)CryGetProcAddress(m_systemDll, DLL_INITFUNC_SYSTEM);
  1782.                 if (CreateSystemInterface)
  1783. #endif // _LIB
  1784.                 {
  1785.                         // initialize the system
  1786.                         m_pSystem = CreateSystemInterface(startupParams);
  1787.                         startupParams.pSystem = m_pSystem;
  1788.                 }
  1789.  
  1790.                 if (!m_pSystem)
  1791.                 {
  1792.                         return false;
  1793.                 }
  1794.         }
  1795.         else
  1796.         {
  1797.                 if (*startupParams.szUserPath)
  1798.                         startupParams.pSystem->ChangeUserPath(startupParams.szUserPath);
  1799.         }
  1800.  
  1801.         ModuleInitISystem(m_pSystem, "CryAction");  // Needed by GetISystem();
  1802.  
  1803.         // here we have gEnv and m_pSystem
  1804.         LOADING_TIME_PROFILE_SECTION_NAMED("CCryAction::Init() after system");
  1805.  
  1806.         InlineInitializationProcessing("CCryAction::Init CrySystem and CryAction init");
  1807.  
  1808.         m_pSystem->GetISystemEventDispatcher()->RegisterListener(&g_system_event_listener_action);
  1809.  
  1810.         // init gEnv->pFlashUI
  1811.  
  1812.         if (gEnv->pRenderer)
  1813.         {
  1814.                 IFlashUIPtr pFlashUI = GetIFlashUIPtr();
  1815.                 m_pSystem->SetIFlashUI(pFlashUI ? pFlashUI.get() : NULL);
  1816.         }
  1817.  
  1818.         //#if CRY_PLATFORM_MAC || CRY_PLATFORM_LINUX || CRY_PLATFORM_ANDROID
  1819.         //   gEnv = m_pSystem->GetGlobalEnvironment();
  1820.         //#endif
  1821.  
  1822.         // fill in interface pointers
  1823.         m_pNetwork = gEnv->pNetwork;
  1824.         m_p3DEngine = gEnv->p3DEngine;
  1825.         m_pScriptSystem = gEnv->pScriptSystem;
  1826.         m_pEntitySystem = gEnv->pEntitySystem;
  1827.         m_pTimer = gEnv->pTimer;
  1828.         m_pLog = gEnv->pLog;
  1829.  
  1830. #if defined(USE_CD_KEYS)
  1831.         #if CRY_PLATFORM_WINDOWS
  1832.         HKEY key;
  1833.         DWORD type;
  1834.         // Open the appropriate registry key
  1835.         LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "", 0,
  1836.                                    KEY_READ | KEY_WOW64_32KEY, &key);
  1837.         if (ERROR_SUCCESS == result)
  1838.         {
  1839.                 std::vector<char> cdkey(32);
  1840.  
  1841.                 DWORD size = cdkey.size();
  1842.  
  1843.                 result = RegQueryValueEx(key, NULL, NULL, &type, (LPBYTE)&cdkey[0], &size);
  1844.  
  1845.                 if (ERROR_SUCCESS == result && type == REG_SZ)
  1846.                 {
  1847.                         m_pNetwork->SetCDKey(&cdkey[0]);
  1848.                 }
  1849.                 else
  1850.                         result = ERROR_BAD_FORMAT;
  1851.         }
  1852.         if (ERROR_SUCCESS != result)
  1853.                 GameWarning("Failed to read CDKey from registry");
  1854.         #endif
  1855. #endif
  1856.  
  1857. #ifdef CRYACTION_DEBUG_MEM
  1858.         DumpMemInfo("CryAction::Init Start");
  1859. #endif
  1860.  
  1861.         InitCVars();
  1862.         InitCommands();
  1863.  
  1864.         InitGameVolumesManager();
  1865.  
  1866.         InlineInitializationProcessing("CCryAction::Init InitCommands");
  1867.         if (m_pSystem->IsDevMode())
  1868.                 m_pDevMode = new CDevMode();
  1869.  
  1870.         m_pTimeDemoRecorder = new CTimeDemoRecorder();
  1871.  
  1872.         CScriptRMI::RegisterCVars();
  1873.         CGameObject::CreateCVars();
  1874.         m_pScriptRMI = new CScriptRMI();
  1875.  
  1876.         // initialize subsystems
  1877.         m_pGameTokenSystem = new CGameTokenSystem;
  1878.         m_pEffectSystem = new CEffectSystem;
  1879.         m_pEffectSystem->Init();
  1880.         m_pUIDraw = new CUIDraw;
  1881.         m_pLevelSystem = new CLevelSystem(m_pSystem, "levels");
  1882.  
  1883.         InlineInitializationProcessing("CCryAction::Init CLevelSystem");
  1884.  
  1885.         m_pActorSystem = new CActorSystem(m_pSystem, m_pEntitySystem);
  1886.         m_pItemSystem = new CItemSystem(this, m_pSystem);
  1887.         m_pActionMapManager = new CActionMapManager(gEnv->pInput);
  1888.  
  1889.         InlineInitializationProcessing("CCryAction::Init CActionMapManager");
  1890.  
  1891.         m_pCooperativeAnimationManager = new CCooperativeAnimationManager;
  1892.  
  1893.         m_pViewSystem = new CViewSystem(m_pSystem);
  1894.         m_pGameplayRecorder = new CGameplayRecorder(this);
  1895.         m_pGameRulesSystem = new CGameRulesSystem(m_pSystem, this);
  1896.         m_pVehicleSystem = new CVehicleSystem(m_pSystem, m_pEntitySystem);
  1897.  
  1898.         m_pSharedParamsManager = new CSharedParamsManager;
  1899.  
  1900.         m_pNetworkCVars = new CNetworkCVars();
  1901.         m_pCryActionCVars = new CCryActionCVars();
  1902.  
  1903.         if (m_pCryActionCVars->g_gameplayAnalyst)
  1904.                 m_pGameplayAnalyst = new CGameplayAnalyst();
  1905.  
  1906.         InlineInitializationProcessing("CCryAction::Init CGameplayAnalyst");
  1907.         m_pGameObjectSystem = new CGameObjectSystem();
  1908.         if (!m_pGameObjectSystem->Init())
  1909.                 return false;
  1910.         else
  1911.         {
  1912.                 // init game object events of CryAction
  1913.                 m_pGameObjectSystem->RegisterEvent(eGFE_PauseGame, "PauseGame");
  1914.                 m_pGameObjectSystem->RegisterEvent(eGFE_ResumeGame, "ResumeGame");
  1915.                 m_pGameObjectSystem->RegisterEvent(eGFE_OnCollision, "OnCollision");
  1916.                 m_pGameObjectSystem->RegisterEvent(eGFE_OnPostStep, "OnPostStep");
  1917.                 m_pGameObjectSystem->RegisterEvent(eGFE_OnStateChange, "OnStateChange");
  1918.                 m_pGameObjectSystem->RegisterEvent(eGFE_ResetAnimationGraphs, "ResetAnimationGraphs");
  1919.                 m_pGameObjectSystem->RegisterEvent(eGFE_OnBreakable2d, "OnBreakable2d");
  1920.                 m_pGameObjectSystem->RegisterEvent(eGFE_OnBecomeVisible, "OnBecomeVisible");
  1921.                 m_pGameObjectSystem->RegisterEvent(eGFE_PreShatter, "PreShatter");
  1922.                 m_pGameObjectSystem->RegisterEvent(eGFE_DisablePhysics, "DisablePhysics");
  1923.                 m_pGameObjectSystem->RegisterEvent(eGFE_EnablePhysics, "EnablePhysics");
  1924.                 m_pGameObjectSystem->RegisterEvent(eGFE_ScriptEvent, "ScriptEvent");
  1925.                 m_pGameObjectSystem->RegisterEvent(eGFE_QueueRagdollCreation, "QueueRagdollCreation");
  1926.                 m_pGameObjectSystem->RegisterEvent(eGFE_RagdollPhysicalized, "RagdollPhysicalized");
  1927.                 m_pGameObjectSystem->RegisterEvent(eGFE_StoodOnChange, "StoodOnChange");
  1928.                 m_pGameObjectSystem->RegisterEvent(eGFE_EnableBlendRagdoll, "EnableBlendToRagdoll");
  1929.                 m_pGameObjectSystem->RegisterEvent(eGFE_DisableBlendRagdoll, "DisableBlendToRagdoll");
  1930.         }
  1931.  
  1932.         m_pAnimationGraphCvars = new CAnimationGraphCVars();
  1933.         m_pMannequin = new CMannequinInterface();
  1934.         if (gEnv->IsEditor())
  1935.                 m_pCallbackTimer = new CallbackTimer();
  1936.         m_pPersistantDebug = new CPersistantDebug();
  1937.         m_pPersistantDebug->Init();
  1938. #if !CRY_PLATFORM_DESKTOP
  1939.         #if PROFILE_CONSOLE_NO_SAVE
  1940.         // Used for demos
  1941.         m_pPlayerProfileManager = new CPlayerProfileManager(new CPlayerProfileImplNoSave());
  1942.         #else
  1943.                 #if CRY_PLATFORM_DURANGO
  1944.         m_pPlayerProfileManager = new CPlayerProfileManager(new CPlayerProfileImplDurango());
  1945.                 #elif CRY_PLATFORM_ORBIS
  1946.         m_pPlayerProfileManager = new CPlayerProfileManager(new CPlayerProfileImplOrbis());
  1947.                 #else
  1948.         m_pPlayerProfileManager = new CPlayerProfileManager(new CPlayerProfileImplConsole());
  1949.                 #endif
  1950.         #endif
  1951. #else
  1952.         m_pPlayerProfileManager = new CPlayerProfileManager(new CPlayerProfileImplFSDir());
  1953. #endif
  1954.         m_pDialogSystem = new CDialogSystem();
  1955.         m_pDialogSystem->Init();
  1956.  
  1957.         m_pTimeOfDayScheduler = new CTimeOfDayScheduler();
  1958.         m_pSubtitleManager = new CSubtitleManager();
  1959.  
  1960.         m_pCustomActionManager = new CCustomActionManager();
  1961.         m_pCustomEventManager = new CCustomEventManager();
  1962.  
  1963.         CRangeSignaling::Create();
  1964.         CSignalTimer::Create();
  1965.  
  1966.         IMovieSystem* movieSys = gEnv->pMovieSystem;
  1967.         if (movieSys != NULL)
  1968.                 movieSys->SetUser(m_pViewSystem);
  1969.  
  1970.         if (m_pVehicleSystem)
  1971.         {
  1972.                 m_pVehicleSystem->Init();
  1973.         }
  1974.  
  1975.         REGISTER_FACTORY((IGameFramework*)this, "Inventory", CInventory, false);
  1976.  
  1977.         if (m_pLevelSystem && m_pItemSystem)
  1978.         {
  1979.                 m_pLevelSystem->AddListener(m_pItemSystem);
  1980.         }
  1981.  
  1982.         InitScriptBinds();
  1983.  
  1984.         ///Disabled as we now use the communication manager exclusively for readabilities
  1985.         //CAIHandler::s_ReadabilityManager.Reload();
  1986.         CAIFaceManager::LoadStatic();
  1987.  
  1988.         // m_pGameRulesSystem = new CGameRulesSystem(m_pSystem, this);
  1989.  
  1990.         // TODO: temporary testing stuff
  1991.         //      REGISTER_COMMAND( "flow_test", FlowTest,VF_NULL,"" );
  1992.  
  1993.         m_pLocalAllocs = new SLocalAllocs();
  1994.  
  1995. #if 0
  1996.         BeginLanQuery();
  1997. #endif
  1998.  
  1999.         if (m_pVehicleSystem)
  2000.                 m_pVehicleSystem->RegisterVehicles(this);
  2001.         if (m_pGameObjectSystem)
  2002.                 m_pGameObjectSystem->RegisterFactories(this);
  2003.         CGameContext::RegisterExtensions(this);
  2004.  
  2005.         // Player profile stuff
  2006.         if (m_pPlayerProfileManager)
  2007.         {
  2008.                 bool ok = m_pPlayerProfileManager->Initialize();
  2009.                 if (!ok)
  2010.                         GameWarning("[PlayerProfiles] CCryAction::Init: Cannot initialize PlayerProfileManager");
  2011.         }
  2012.  
  2013. #ifdef CRYACTION_DEBUG_MEM
  2014.         DumpMemInfo("CryAction::Init End");
  2015. #endif
  2016.  
  2017.         m_pGFListeners = new TGameFrameworkListeners();
  2018.  
  2019.         // These vectors must have enough space allocated up-front so as to guarantee no further allocs
  2020.         // If they do exceed this capacity, the level heap mechanism should result in a crash
  2021.         m_pGFListeners->reserve(20);
  2022.         m_validListeners.reserve(m_pGFListeners->capacity());
  2023.  
  2024.         m_nextFrameCommand = new string();
  2025.  
  2026.         m_pGameStatsConfig = new CGameStatsConfig();
  2027.         m_pGameStatsConfig->ReadConfig();
  2028.  
  2029.         //      InlineInitializationProcessing("CCryAction::Init m_pCharacterPartsManager");
  2030.  
  2031.         m_pGameStatistics = new CGameStatistics();
  2032.  
  2033.         if (gEnv->pAISystem)
  2034.         {
  2035.                 m_pAIDebugRenderer = new CAIDebugRenderer(gEnv->pRenderer);
  2036.                 gEnv->pAISystem->SetAIDebugRenderer(m_pAIDebugRenderer);
  2037.  
  2038.                 m_pAINetworkDebugRenderer = new CAINetworkDebugRenderer(gEnv->pRenderer);
  2039.                 gEnv->pAISystem->SetAINetworkDebugRenderer(m_pAINetworkDebugRenderer);
  2040.  
  2041.                 RegisterActionBehaviorTreeNodes();
  2042.         }
  2043.  
  2044.         if (gEnv->IsEditor())
  2045.                 CreatePhysicsQueues();
  2046.  
  2047.         XMLCPB::CDebugUtils::Create();
  2048.  
  2049.         if (!gEnv->IsDedicated())
  2050.         {
  2051.                 XMLCPB::InitializeCompressorThread();
  2052.         }
  2053.  
  2054.         m_pNetMsgDispatcher = new CNetMessageDistpatcher();
  2055.         m_pManualFrameStepController = new CManualFrameStepController();
  2056.  
  2057.         if (gEnv->pRenderer)
  2058.         {
  2059.                 m_pColorGradientManager = new CColorGradientManager();
  2060.         }
  2061.  
  2062.         InitGame(startupParams);
  2063.  
  2064.         if (startupParams.bExecuteCommandLine)
  2065.                 GetISystem()->ExecuteCommandLine();
  2066.  
  2067.         // game got initialized, time to finalize framework initialization
  2068.         if (CompleteInit())
  2069.         {
  2070.                 InlineInitializationProcessing("CCryAction::Init End");
  2071.  
  2072.                 gEnv->pSystem->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_GAME_FRAMEWORK_INIT_DONE, 0, 0);
  2073.  
  2074.                 gEnv->pConsole->ExecuteString("exec autoexec.cfg");
  2075.  
  2076.                 // run main game loop
  2077.                 if (startupParams.bManualEngineLoop)
  2078.                 {
  2079.                         return true;
  2080.                 }
  2081.                 else
  2082.                 {
  2083.                         return (Run("") != 0);
  2084.                 }
  2085.         }
  2086.  
  2087.         return false;
  2088. }
  2089.  
  2090. bool CCryAction::InitGame(SSystemInitParams& startupParams)
  2091. {
  2092.         if (ICVar* pCVarGameDir = gEnv->pConsole->GetCVar("sys_dll_game"))
  2093.         {
  2094.                 const char* gameDLLName = pCVarGameDir->GetString();
  2095.                 if (strlen(gameDLLName) == 0)
  2096.                         return false;
  2097.  
  2098.                 HMODULE hGameDll = 0;
  2099.  
  2100. #if !defined(_LIB)
  2101.                 hGameDll = CryLoadLibrary(gameDLLName);
  2102.  
  2103.                 if (!hGameDll)
  2104.                 {
  2105.                         CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to load the Game DLL! %s", gameDLLName);
  2106.                         return false;
  2107.                 }
  2108.  
  2109.                 IGameStartup::TEntryFunction CreateGameStartup = (IGameStartup::TEntryFunction)CryGetProcAddress(hGameDll, "CreateGameStartup");
  2110.                 if (!CreateGameStartup)
  2111.                 {
  2112.                         CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to find the GameStartup Interface in %s!", gameDLLName);
  2113.                         CryFreeLibrary(hGameDll);
  2114.                         return false;
  2115.                 }
  2116. #endif
  2117.  
  2118.                 // create the game startup interface
  2119.                 IGameStartup* pGameStartup = CreateGameStartup();
  2120.                 if (!pGameStartup)
  2121.                 {
  2122.                         CryWarning(VALIDATOR_MODULE_SYSTEM, VALIDATOR_WARNING, "Failed to find the GameStartup Interface in %s!", gameDLLName);
  2123.                         CryFreeLibrary(hGameDll);
  2124.                         return false;
  2125.                 }
  2126.  
  2127.                 startupParams.pGameStartup = pGameStartup;
  2128.                 if (m_externalGameLibrary.pGame = pGameStartup->Init(startupParams))
  2129.                 {
  2130.                         m_externalGameLibrary.dllName = gameDLLName;
  2131.                         m_externalGameLibrary.dllHandle = hGameDll;
  2132.                         m_externalGameLibrary.pGameStartup = pGameStartup;
  2133.                 }
  2134.         }
  2135.  
  2136.         return m_externalGameLibrary.IsValid();
  2137. }
  2138.  
  2139. //------------------------------------------------------------------------
  2140. int CCryAction::Run(const char* szAutoStartLevelName)
  2141. {
  2142.         if (szAutoStartLevelName[0])
  2143.         {
  2144.                 //load savegame
  2145.                 if (CryStringUtils::stristr(szAutoStartLevelName, CRY_SAVEGAME_FILE_EXT) != 0)
  2146.                 {
  2147.                         CryFixedStringT<256> fileName(szAutoStartLevelName);
  2148.                         // NOTE! two step trimming is intended!
  2149.                         fileName.Trim(" ");  // first:  remove enclosing spaces (outside ")
  2150.                         fileName.Trim("\""); // second: remove potential enclosing "
  2151.                         gEnv->pGameFramework->LoadGame(fileName.c_str());
  2152.                 }
  2153.                 else  //start specified level
  2154.                 {
  2155.                         CryFixedStringT<256> mapCmd("map ");
  2156.                         mapCmd += szAutoStartLevelName;
  2157.                         gEnv->pConsole->ExecuteString(mapCmd.c_str());
  2158.                 }
  2159.         }
  2160.  
  2161. #if CRY_PLATFORM_WINDOWS
  2162.         if (!(gEnv && gEnv->pSystem) || (!gEnv->IsEditor() && !gEnv->IsDedicated()))
  2163.         {
  2164.                 ::ShowCursor(FALSE);
  2165.                 if (GetISystem()->GetIHardwareMouse())
  2166.                         GetISystem()->GetIHardwareMouse()->DecrementCounter();
  2167.         }
  2168. #else
  2169.         if (gEnv && gEnv->pHardwareMouse)
  2170.                 gEnv->pHardwareMouse->DecrementCounter();
  2171. #endif
  2172.  
  2173. #if defined(CRY_PLATFORM_DURANGO)
  2174.         return 1;
  2175. #endif
  2176.  
  2177.         for (;; )
  2178.         {
  2179.                 if (!Update(true, 0))
  2180.                 {
  2181.                         break;
  2182.                 }
  2183.         }
  2184.  
  2185.         return 0;
  2186. }
  2187.  
  2188. //------------------------------------------------------------------------
  2189. int CCryAction::ManualFrameUpdate(bool haveFocus, unsigned int updateFlags)
  2190. {
  2191.         return Update(haveFocus, updateFlags);
  2192. }
  2193.  
  2194. //------------------------------------------------------------------------
  2195. int CCryAction::Update(bool haveFocus, unsigned int updateFlags)
  2196. {
  2197.         // The frame profile system already creates an "overhead" profile label
  2198.         // in StartFrame(). Hence we have to set the FRAMESTART before.
  2199.         CRY_PROFILE_FRAMESTART("Main");
  2200.  
  2201. #if defined(JOBMANAGER_SUPPORT_PROFILING)
  2202.         gEnv->GetJobManager()->SetFrameStartTime(gEnv->pTimer->GetAsyncTime());
  2203. #endif
  2204.  
  2205.         if (gEnv->pConsole)
  2206.         {
  2207. #if CRY_PLATFORM_WINDOWS
  2208.                 if (gEnv && gEnv->pRenderer && gEnv->pRenderer->GetHWND())
  2209.                 {
  2210.                         bool focus = (::GetFocus() == gEnv->pRenderer->GetHWND());
  2211.                         static bool focused = focus;
  2212.                         if (focus != focused)
  2213.                         {
  2214.                                 if (GetISystem()->GetISystemEventDispatcher())
  2215.                                 {
  2216.                                         GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_CHANGE_FOCUS, focus, 0);
  2217.                                 }
  2218.                                 focused = focus;
  2219.                         }
  2220.                 }
  2221. #endif
  2222.         }
  2223.  
  2224.         bool bBlockUpdate = false;
  2225.  
  2226.         if (m_pManualFrameStepController)
  2227.         {
  2228.                 const auto manualStepResult = m_pManualFrameStepController->Update();
  2229.                 bBlockUpdate = (manualStepResult == EManualFrameStepResult::Block);
  2230.         }
  2231.  
  2232.         bool bRun = bBlockUpdate;
  2233.         int gameUpdateResult = 1;
  2234.  
  2235.         if (!bBlockUpdate)
  2236.         {
  2237.                 bRun = PreUpdate(haveFocus, updateFlags);
  2238.  
  2239.                 if (auto* pGame = CCryAction::GetCryAction()->GetIGame())
  2240.                 {
  2241.                         gameUpdateResult = pGame->Update(haveFocus, updateFlags);
  2242.                 }
  2243.  
  2244.                 PostUpdate(haveFocus, updateFlags);
  2245.         }
  2246.  
  2247.         /*
  2248.            if (!m_fullScreenCVarSetup && gEnv->pConsole)
  2249.            {
  2250.             ICVar* pVar = gEnv->pConsole->GetCVar("r_Fullscreen");
  2251.             if (pVar)
  2252.             {
  2253.               pVar->SetOnChangeCallback(FullScreenCVarChanged);
  2254.               m_fullScreenCVarSetup = true;
  2255.             }
  2256.            }
  2257.          */
  2258.  
  2259. #if ENABLE_AUTO_TESTER
  2260.         s_autoTesterSingleton.Update();
  2261. #endif
  2262.  
  2263.         return (bRun && (gameUpdateResult > 0)) ? 1 : 0;
  2264. }
  2265.  
  2266. //------------------------------------------------------------------------
  2267. void CCryAction::InitForceFeedbackSystem()
  2268. {
  2269.         LOADING_TIME_PROFILE_SECTION;
  2270.         SAFE_DELETE(m_pForceFeedBackSystem);
  2271.         m_pForceFeedBackSystem = new CForceFeedBackSystem();
  2272.         m_pForceFeedBackSystem->Initialize();
  2273. }
  2274.  
  2275. //------------------------------------------------------------------------
  2276.  
  2277. void CCryAction::InitGameVolumesManager()
  2278. {
  2279.         if (m_pGameVolumesManager == NULL)
  2280.         {
  2281.                 m_pGameVolumesManager = new CGameVolumesManager();
  2282.         }
  2283. }
  2284.  
  2285. //------------------------------------------------------------------------
  2286. void CCryAction::InitGameType(bool multiplayer, bool fromInit)
  2287. {
  2288.         gEnv->pSystem->SetSystemGlobalState(ESYSTEM_GLOBAL_STATE_RUNNING);
  2289.         SAFE_DELETE(m_pGameSerialize);
  2290.  
  2291.         InitForceFeedbackSystem();
  2292.  
  2293. #if !defined(DEDICATED_SERVER)
  2294.         if (!multiplayer)
  2295.         {
  2296.                 m_pGameSerialize = new CGameSerialize();
  2297.  
  2298.                 if (m_pGameSerialize)
  2299.                         m_pGameSerialize->RegisterFactories(this);
  2300.         }
  2301.  
  2302.         ICVar* pEnableAI = gEnv->pConsole->GetCVar("sv_AISystem");
  2303.         if (!multiplayer || (pEnableAI && pEnableAI->GetIVal()))
  2304.         {
  2305.                 if (!m_pAIProxyManager)
  2306.                 {
  2307.                         m_pAIProxyManager = new CAIProxyManager;
  2308.                         m_pAIProxyManager->Init();
  2309.                 }
  2310.         }
  2311.         else
  2312. #endif
  2313.         {
  2314.                 if (m_pAIProxyManager)
  2315.                 {
  2316.                         m_pAIProxyManager->Shutdown();
  2317.                         SAFE_DELETE(m_pAIProxyManager);
  2318.                 }
  2319.         }
  2320. }
  2321.  
  2322. static std::vector<const char*> gs_lipSyncExtensionNamesForExposureToEditor;
  2323.  
  2324. //------------------------------------------------------------------------
  2325. bool CCryAction::CompleteInit()
  2326. {
  2327.         LOADING_TIME_PROFILE_SECTION;
  2328. #ifdef CRYACTION_DEBUG_MEM
  2329.         DumpMemInfo("CryAction::CompleteInit Start");
  2330. #endif
  2331.  
  2332.         InlineInitializationProcessing("CCryAction::CompleteInit");
  2333.  
  2334.         REGISTER_FACTORY((IGameFramework*)this, "AnimatedCharacter", CAnimatedCharacter, false);
  2335.         REGISTER_FACTORY((IGameFramework*)this, "LipSync_TransitionQueue", CLipSync_TransitionQueue, false);
  2336.         REGISTER_FACTORY((IGameFramework*)this, "LipSync_FacialInstance", CLipSync_FacialInstance, false);
  2337.         gs_lipSyncExtensionNamesForExposureToEditor.clear();
  2338.         gs_lipSyncExtensionNamesForExposureToEditor.push_back("LipSync_TransitionQueue");
  2339.         gs_lipSyncExtensionNamesForExposureToEditor.push_back("LipSync_FacialInstance");
  2340.  
  2341.         EndGameContext();
  2342.  
  2343.         // init IFlashUI extension
  2344.         if (gEnv->pFlashUI)
  2345.                 gEnv->pFlashUI->Init();
  2346.  
  2347.         SAFE_DELETE(m_pFlowSystem);
  2348.         m_pFlowSystem = new CFlowSystem();
  2349.         m_pSystem->SetIFlowSystem(m_pFlowSystem);
  2350.         m_pFlowSystem->PreInit();
  2351.         m_pSystem->SetIDialogSystem(m_pDialogSystem);
  2352.  
  2353.         if (m_pFlowSystem)
  2354.                 m_pFlowSystem->Init();
  2355.  
  2356.         InlineInitializationProcessing("CCryAction::CompleteInit SetDialogSystem");
  2357.  
  2358.         if (m_pGameplayAnalyst)
  2359.                 m_pGameplayRecorder->RegisterListener(m_pGameplayAnalyst);
  2360.  
  2361.         CRangeSignaling::ref().Init();
  2362.         CSignalTimer::ref().Init();
  2363.         // ---------------------------
  2364.  
  2365.         m_pMaterialEffects = new CMaterialEffects();
  2366.         m_pScriptBindMFX = new CScriptBind_MaterialEffects(m_pSystem, m_pMaterialEffects);
  2367.         m_pSystem->SetIMaterialEffects(m_pMaterialEffects);
  2368.  
  2369.         InlineInitializationProcessing("CCryAction::CompleteInit MaterialEffects");
  2370.  
  2371.         m_pBreakableGlassSystem = new CBreakableGlassSystem();
  2372.  
  2373.         InitForceFeedbackSystem();
  2374.  
  2375.         ICVar* pEnableAI = gEnv->pConsole->GetCVar("sv_AISystem");
  2376.         if (!gEnv->bMultiplayer || (pEnableAI && pEnableAI->GetIVal()))
  2377.         {
  2378.                 m_pAIProxyManager = new CAIProxyManager;
  2379.                 m_pAIProxyManager->Init();
  2380.         }
  2381.  
  2382. #ifdef SEG_WORLD
  2383.         if (!gEnv->IsEditor())
  2384.                 m_pSegmentedWorld = new CSegmentedWorld();
  2385. #endif
  2386.  
  2387.         // in pure game mode we load the equipment packs from disk
  2388.         // in editor mode, this is done in GameEngine.cpp
  2389.         if ((m_pItemSystem) && (gEnv->IsEditor() == false))
  2390.         {
  2391.                 LOADING_TIME_PROFILE_SECTION_NAMED("CCryAction::CompleteInit(): EquipmentPacks");
  2392.                 m_pItemSystem->GetIEquipmentManager()->DeleteAllEquipmentPacks();
  2393.                 m_pItemSystem->GetIEquipmentManager()->LoadEquipmentPacksFromPath("Libs/EquipmentPacks");
  2394.         }
  2395.  
  2396.         InlineInitializationProcessing("CCryAction::CompleteInit EquipmentPacks");
  2397.  
  2398.         gEnv->p3DEngine->GetMaterialManager()->GetDefaultLayersMaterial();
  2399.  
  2400.         if (auto* pGame = CCryAction::GetCryAction()->GetIGame())
  2401.         {
  2402.                 pGame->CompleteInit();
  2403.         }
  2404.  
  2405.         InlineInitializationProcessing("CCryAction::CompleteInit LoadFlowGraphLibs");
  2406.  
  2407.         // load flowgraphs (done after Game has initialized, because it might add additional flownodes)
  2408.         if (m_pMaterialEffects)
  2409.                 m_pMaterialEffects->LoadFlowGraphLibs();
  2410.  
  2411.         if (!m_pScriptRMI->Init())
  2412.                 return false;
  2413.  
  2414.         if (gEnv->pFlashUI)
  2415.                 gEnv->pFlashUI->PostInit();
  2416.         InlineInitializationProcessing("CCryAction::CompleteInit FlashUI");
  2417.  
  2418.         // after everything is initialized, run our main script
  2419.         m_pScriptSystem->ExecuteFile("scripts/main.lua");
  2420.         m_pScriptSystem->BeginCall("OnInit");
  2421.         m_pScriptSystem->EndCall();
  2422.  
  2423.         InlineInitializationProcessing("CCryAction::CompleteInit RunMainScript");
  2424.  
  2425. #ifdef CRYACTION_DEBUG_MEM
  2426.         DumpMemInfo("CryAction::CompleteInit End");
  2427. #endif
  2428.  
  2429.         CBreakReplicator::RegisterClasses();
  2430.  
  2431.         if (gEnv->pAISystem)
  2432.                 gEnv->pAISystem->CompleteInit();
  2433.  
  2434.         if (gEnv->pRenderer)
  2435.         {
  2436.                 gEnv->pRenderer->StopRenderIntroMovies(true);
  2437.         }
  2438.  
  2439.         GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_GAME_POST_INIT, 0, 0);
  2440.         GetISystem()->GetISystemEventDispatcher()->OnSystemEvent(ESYSTEM_EVENT_GAME_POST_INIT_DONE, 0, 0);
  2441.  
  2442.         if (gEnv->pMaterialEffects)
  2443.         {
  2444.                 gEnv->pMaterialEffects->CompleteInit();
  2445.         }
  2446.  
  2447.         if (gEnv->pConsole->GetCVar("g_enableMergedMeshRuntimeAreas")->GetIVal() > 0)
  2448.         {
  2449.                 m_pRuntimeAreaManager = new CRuntimeAreaManager();
  2450.         }
  2451.  
  2452. #if defined(CRY_UNIT_TESTING)
  2453.         if (CryUnitTest::IUnitTestManager* pTestManager = GetISystem()->GetITestSystem()->GetIUnitTestManager())
  2454.         {
  2455.         #if defined(_LIB)
  2456.                 pTestManager->CreateTests(CryUnitTest::Test::m_pFirst, "StaticBinary");
  2457.         #endif
  2458.  
  2459.                 const ICmdLineArg* pSkipUnitTest = GetISystem()->GetICmdLine()->FindArg(eCLAT_Pre, "skip_unit_tests");
  2460.                 if (!pSkipUnitTest)
  2461.                 {
  2462.                         const ICmdLineArg* pUseUnitTestExcelReporter = GetISystem()->GetICmdLine()->FindArg(eCLAT_Pre, "use_unit_test_excel_reporter");
  2463.                         if (pUseUnitTestExcelReporter)
  2464.                         {
  2465.                                 GetISystem()->GetITestSystem()->GetIUnitTestManager()->RunAllTests(CryUnitTest::ExcelReporter);
  2466.                         }
  2467.                         else
  2468.                         {
  2469.                                 GetISystem()->GetITestSystem()->GetIUnitTestManager()->RunAllTests(CryUnitTest::MinimalReporter);
  2470.                         }
  2471.                 }
  2472.         }
  2473. #endif
  2474.  
  2475.         InlineInitializationProcessing("CCryAction::CompleteInit End");
  2476.         return true;
  2477. }
  2478.  
  2479. //------------------------------------------------------------------------
  2480. void CCryAction::InitScriptBinds()
  2481. {
  2482.         m_pScriptNet = new CScriptBind_Network(m_pSystem, this);
  2483.         m_pScriptA = new CScriptBind_Action(this);
  2484.         m_pScriptIS = new CScriptBind_ItemSystem(m_pSystem, m_pItemSystem, this);
  2485.         m_pScriptAS = new CScriptBind_ActorSystem(m_pSystem, this);
  2486.         m_pScriptAMM = new CScriptBind_ActionMapManager(m_pSystem, m_pActionMapManager);
  2487.  
  2488.         m_pScriptVS = new CScriptBind_VehicleSystem(m_pSystem, m_pVehicleSystem);
  2489.         m_pScriptBindVehicle = new CScriptBind_Vehicle(m_pSystem, this);
  2490.         m_pScriptBindVehicleSeat = new CScriptBind_VehicleSeat(m_pSystem, this);
  2491.  
  2492.         m_pScriptInventory = new CScriptBind_Inventory(m_pSystem, this);
  2493.         m_pScriptBindDS = new CScriptBind_DialogSystem(m_pSystem, m_pDialogSystem);
  2494.         m_pScriptBindUIAction = new CScriptBind_UIAction();
  2495. }
  2496.  
  2497. //------------------------------------------------------------------------
  2498. void CCryAction::ReleaseScriptBinds()
  2499. {
  2500.         // before we release script binds call out main "OnShutdown"
  2501.         if (m_pScriptSystem)
  2502.         {
  2503.                 m_pScriptSystem->BeginCall("OnShutdown");
  2504.                 m_pScriptSystem->EndCall();
  2505.         }
  2506.  
  2507.         SAFE_RELEASE(m_pScriptA);
  2508.         SAFE_RELEASE(m_pScriptIS);
  2509.         SAFE_RELEASE(m_pScriptAS);
  2510.         SAFE_RELEASE(m_pScriptAMM);
  2511.         SAFE_RELEASE(m_pScriptVS);
  2512.         SAFE_RELEASE(m_pScriptNet);
  2513.         SAFE_RELEASE(m_pScriptBindVehicle);
  2514.         SAFE_RELEASE(m_pScriptBindVehicleSeat);
  2515.         SAFE_RELEASE(m_pScriptInventory);
  2516.         SAFE_RELEASE(m_pScriptBindDS);
  2517.         SAFE_RELEASE(m_pScriptBindMFX);
  2518.         SAFE_RELEASE(m_pScriptBindUIAction);
  2519. }
  2520.  
  2521. //------------------------------------------------------------------------
  2522. bool CCryAction::ShutdownGame()
  2523. {
  2524.         // unload game dll if present
  2525.         if (m_externalGameLibrary.IsValid())
  2526.         {
  2527.                 CFlowGraphModuleManager* pFlowGraphModuleManager = m_pFlowSystem->GetModuleManager();
  2528.                 if (pFlowGraphModuleManager)
  2529.                 {
  2530.                         pFlowGraphModuleManager->ClearModules();
  2531.                 }
  2532.  
  2533.                 IMaterialEffects* pMaterialEffects = GetIMaterialEffects();
  2534.                 if (pMaterialEffects)
  2535.                 {
  2536.                         pMaterialEffects->Reset(true);
  2537.                 }
  2538.  
  2539.                 IFlashUI* pFlashUI = gEnv->pFlashUI;
  2540.                 if (pFlashUI)
  2541.                 {
  2542.                         pFlashUI->ClearUIActions();
  2543.                 }
  2544.  
  2545.                 m_externalGameLibrary.pGameStartup->Shutdown();
  2546.                 if (m_externalGameLibrary.dllHandle)
  2547.                 {
  2548.                         CryFreeLibrary(m_externalGameLibrary.dllHandle);
  2549.                 }
  2550.                 m_externalGameLibrary.Reset();
  2551.         }
  2552.  
  2553.         return true;
  2554. }
  2555.  
  2556. //------------------------------------------------------------------------
  2557. void CCryAction::ShutdownEngine()
  2558. {
  2559.         ShutdownGame();
  2560.  
  2561.         XMLCPB::ShutdownCompressorThread();
  2562.  
  2563.         SAFE_DELETE(m_pAIDebugRenderer);
  2564.         SAFE_DELETE(m_pAINetworkDebugRenderer);
  2565.  
  2566.         if (s_rcon_server)
  2567.                 s_rcon_server->Stop();
  2568.         if (s_rcon_client)
  2569.                 s_rcon_client->Disconnect();
  2570.         s_rcon_server = NULL;
  2571.         s_rcon_client = NULL;
  2572.  
  2573.         if (s_http_server)
  2574.                 s_http_server->Stop();
  2575.         s_http_server = NULL;
  2576.  
  2577.         if (m_pGameplayAnalyst)
  2578.                 m_pGameplayRecorder->UnregisterListener(m_pGameplayAnalyst);
  2579.  
  2580.         if (gEnv)
  2581.         {
  2582.                 EndGameContext();
  2583.         }
  2584.  
  2585.         if (m_pEntitySystem)
  2586.         {
  2587.                 m_pEntitySystem->Unload();
  2588.         }
  2589.  
  2590.         if (gEnv)
  2591.         {
  2592.                 IMovieSystem* movieSys = gEnv->pMovieSystem;
  2593.                 if (movieSys != NULL)
  2594.                         movieSys->SetUser(NULL);
  2595.         }
  2596.  
  2597.         // profile manager needs to shut down (logout users, ...)
  2598.         // while most systems are still up
  2599.         if (m_pPlayerProfileManager)
  2600.                 m_pPlayerProfileManager->Shutdown();
  2601.  
  2602.         if (m_pDialogSystem)
  2603.                 m_pDialogSystem->Shutdown();
  2604.  
  2605.         if (m_pFlowSystem)
  2606.                 m_pFlowSystem->Shutdown();
  2607.  
  2608.         SAFE_RELEASE(m_pActionMapManager);
  2609.         SAFE_RELEASE(m_pItemSystem);
  2610.         SAFE_RELEASE(m_pLevelSystem);
  2611.         SAFE_RELEASE(m_pViewSystem);
  2612.         SAFE_RELEASE(m_pGameplayRecorder);
  2613.         SAFE_RELEASE(m_pGameplayAnalyst);
  2614.         SAFE_RELEASE(m_pGameRulesSystem);
  2615.         SAFE_RELEASE(m_pSharedParamsManager);
  2616.         SAFE_RELEASE(m_pVehicleSystem);
  2617.         SAFE_DELETE(m_pMaterialEffects);
  2618.         SAFE_DELETE(m_pBreakableGlassSystem);
  2619.         SAFE_RELEASE(m_pActorSystem);
  2620.         SAFE_DELETE(m_pForceFeedBackSystem);
  2621.         SAFE_DELETE(m_pSubtitleManager);
  2622.         SAFE_DELETE(m_pUIDraw);
  2623.         SAFE_DELETE(m_pScriptRMI);
  2624.         SAFE_DELETE(m_pGameTokenSystem);
  2625.         SAFE_DELETE(m_pEffectSystem);
  2626.         SAFE_DELETE(m_pAnimationGraphCvars);
  2627.         SAFE_DELETE(m_pGameObjectSystem);
  2628.         SAFE_DELETE(m_pMannequin);
  2629.         SAFE_DELETE(m_pTimeDemoRecorder);
  2630.         SAFE_DELETE(m_pGameSerialize);
  2631.         SAFE_DELETE(m_pPersistantDebug);
  2632.         SAFE_DELETE(m_pPlayerProfileManager);
  2633.         SAFE_DELETE(m_pDialogSystem); // maybe delete before
  2634.         SAFE_DELETE(m_pTimeOfDayScheduler);
  2635.         SAFE_DELETE(m_pLocalAllocs);
  2636.         SAFE_DELETE(m_pCooperativeAnimationManager);
  2637.         SAFE_DELETE(m_pGameSessionHandler);
  2638.         SAFE_DELETE(m_pCustomEventManager)
  2639.         SAFE_DELETE(m_pCustomActionManager)
  2640.  
  2641.         SAFE_DELETE(m_pGameVolumesManager);
  2642.  
  2643.         SAFE_DELETE(m_pRuntimeAreaManager);
  2644.  
  2645.         ReleaseScriptBinds();
  2646.         ReleaseCVars();
  2647.  
  2648.         SAFE_DELETE(m_pColorGradientManager);
  2649.  
  2650.         SAFE_DELETE(m_pDevMode);
  2651.         SAFE_DELETE(m_pCallbackTimer);
  2652.         SAFE_DELETE(m_pSegmentedWorld);
  2653.  
  2654.         CSignalTimer::Shutdown();
  2655.         CRangeSignaling::Shutdown();
  2656.  
  2657.         if (m_pAIProxyManager)
  2658.         {
  2659.                 m_pAIProxyManager->Shutdown();
  2660.                 SAFE_DELETE(m_pAIProxyManager);
  2661.         }
  2662.  
  2663.         SAFE_DELETE(m_pManualFrameStepController);
  2664.         SAFE_DELETE(m_pNetMsgDispatcher);
  2665.  
  2666.         ReleaseExtensions();
  2667.  
  2668.         // Shutdown pFlashUI after shutdown since FlowSystem will hold UIFlowNodes until deletion
  2669.         // this will allow clean dtor for all UIFlowNodes
  2670.         if (gEnv && gEnv->pFlashUI)
  2671.                 gEnv->pFlashUI->Shutdown();
  2672.  
  2673.         // Nodes might try to access the FlowSystem at any time therefore
  2674.         // keep it around until the last node has been destroyed.
  2675.         SAFE_RELEASE(m_pFlowSystem);
  2676.         if (m_pSystem)
  2677.         {
  2678.                 m_pSystem->SetIFlowSystem(nullptr);
  2679.         }
  2680.  
  2681.         SAFE_DELETE(m_pGFListeners);
  2682.  
  2683.         XMLCPB::CDebugUtils::Destroy();
  2684.  
  2685.         if (m_pSystem)
  2686.         {
  2687.                 m_pSystem->GetISystemEventDispatcher()->RemoveListener(&g_system_event_listener_action);
  2688.         }
  2689.  
  2690.         // having a dll handle means we did create the system interface
  2691.         // so we must release it
  2692.         SAFE_RELEASE(m_pSystem);
  2693.         if (m_systemDll)
  2694.         {
  2695.                 CryFreeLibrary(m_systemDll);
  2696.                 m_systemDll = 0;
  2697.         }
  2698.  
  2699.         SAFE_DELETE(m_nextFrameCommand);
  2700.         SAFE_DELETE(m_pPhysicsQueues);
  2701.  
  2702.         m_pThis = 0;
  2703.         gEnv->pGameFramework = nullptr;
  2704. }
  2705.  
  2706. //------------------------------------------------------------------------
  2707. void CCryAction::ShutdownEngineFast()
  2708. {
  2709.         IForceFeedbackSystem* pForceFeedbackSystem = GetIForceFeedbackSystem();
  2710.         if (pForceFeedbackSystem)
  2711.         {
  2712.                 CryLogAlways("ActionGame - Shutting down all force feedback");
  2713.                 pForceFeedbackSystem->StopAllEffects();
  2714.         }
  2715.  
  2716.         //Ensure that the load ticker is not currently running. It can perform tasks on the network systems while they're being shut down
  2717.         StopNetworkStallTicker();
  2718.  
  2719.         ShutdownGame();
  2720. }
  2721.  
  2722. //------------------------------------------------------------------------
  2723. f32 g_fPrintLine = 0.0f;
  2724.  
  2725. void CCryAction::PrePhysicsUpdate()
  2726. {
  2727.         if (auto* pGame = GetIGame())
  2728.         {
  2729.                 pGame->PrePhysicsUpdate();  // required if PrePhysicsUpdate() is overriden in game
  2730.         }
  2731. }
  2732.  
  2733. bool CCryAction::PreUpdate(bool haveFocus, unsigned int updateFlags)
  2734. {
  2735.         LOADING_TIME_PROFILE_SECTION(gEnv->pSystem);
  2736.  
  2737.         if (!(updateFlags & ESYSUPDATE_EDITOR))
  2738.                 gEnv->pFrameProfileSystem->StartFrame();
  2739.  
  2740.         // Earliest point of adding profile labels
  2741.         CRY_PROFILE_REGION(PROFILE_GAME, "CCryAction::PreUpdate");
  2742.         CRYPROFILE_SCOPE_PROFILE_MARKER("CCryAction::PreUpdate");
  2743.  
  2744.         g_fPrintLine = 10.0f;
  2745.  
  2746.         if (!m_nextFrameCommand->empty())
  2747.         {
  2748.                 gEnv->pConsole->ExecuteString(*m_nextFrameCommand);
  2749.                 m_nextFrameCommand->resize(0);
  2750.         }
  2751.  
  2752.         CheckEndLevelSchedule();
  2753.  
  2754. #if !defined(_RELEASE)
  2755.         CheckConnectRepeatedly();   // handle repeated connect mode - mainly for autotests to not get broken by timeouts on initial connect
  2756. #endif
  2757.  
  2758.         if (ITextModeConsole* pTextModeConsole = gEnv->pSystem->GetITextModeConsole())
  2759.                 pTextModeConsole->BeginDraw();
  2760.  
  2761.         /*
  2762.            IRenderer * pRend = gEnv->pRenderer;
  2763.            float white[4] = {1,1,1,1};
  2764.            pRend->Draw2dLabel( 10, 10, 3, white, false, "TIME: %f", gEnv->pTimer->GetFrameStartTime().GetSeconds() );
  2765.          */
  2766.         bool gameRunning = IsGameStarted();
  2767.  
  2768.         bool bGameIsPaused = !gameRunning || IsGamePaused(); // slightly different from m_paused (check's gEnv->pTimer as well)
  2769.         if (m_pTimeDemoRecorder && !IsGamePaused())
  2770.                 m_pTimeDemoRecorder->PreUpdate();
  2771.  
  2772.         // TODO: Craig - this probably needs to be updated after CSystem::Update
  2773.         // update the callback system
  2774.         if (!bGameIsPaused)
  2775.         {
  2776.                 if (m_pCallbackTimer)
  2777.                         m_pCallbackTimer->Update();
  2778.         }
  2779.  
  2780.         bool bRetRun = true;
  2781.  
  2782.         //////////////////////////////////////////////////////////////////////
  2783.         // tell the network to go to sleep
  2784.         if (gEnv->pNetwork)
  2785.         {
  2786.                 gEnv->pNetwork->SyncWithGame(eNGS_SleepNetwork);
  2787.         }
  2788.  
  2789.         m_pSystem->RenderBegin();
  2790.  
  2791.         float frameTime(gEnv->pTimer->GetFrameTime());
  2792.  
  2793.         LARGE_INTEGER updateStart, updateEnd;
  2794.         updateStart.QuadPart = 0;
  2795.         updateEnd.QuadPart = 0;
  2796.  
  2797.         // when we are updated by the editor, we should not update the system
  2798.         if (!(updateFlags & ESYSUPDATE_EDITOR))
  2799.         {
  2800.                 int updateLoopPaused = (!gameRunning || m_paused) ? 1 : 0;
  2801.                 if (gEnv->pRenderer && gEnv->pRenderer->IsPost3DRendererEnabled())
  2802.                 {
  2803.                         updateLoopPaused = 0;
  2804.                         updateFlags |= ESYSUPDATE_IGNORE_AI;
  2805.                 }
  2806.  
  2807.                 const bool bGameWasPaused = bGameIsPaused;
  2808.  
  2809.                 if (!bGameIsPaused && m_pSegmentedWorld)
  2810.                 {
  2811.                         m_pSegmentedWorld->Update();
  2812.                 }
  2813.  
  2814.                 bRetRun = m_pSystem->Update(updateFlags, updateLoopPaused);
  2815. #ifdef ENABLE_LW_PROFILERS
  2816.                 CRY_PROFILE_SECTION(PROFILE_ACTION, "ActionPreUpdate");
  2817.                 QueryPerformanceCounter(&updateStart);
  2818. #endif
  2819.                 // notify listeners
  2820.                 OnActionEvent(SActionEvent(eAE_earlyPreUpdate));
  2821.  
  2822.                 // during m_pSystem->Update call the Game might have been paused or un-paused
  2823.                 gameRunning = IsGameStarted() && m_pGame && m_pGame->IsInited();
  2824.                 bGameIsPaused = !gameRunning || IsGamePaused();
  2825.  
  2826.                 if (!bGameIsPaused && !bGameWasPaused) // don't update gameplayrecorder if paused
  2827.                         if (m_pGameplayRecorder)
  2828.                                 m_pGameplayRecorder->Update(frameTime);
  2829.  
  2830.                 if (!bGameIsPaused && gameRunning)
  2831.                 {
  2832.                         if (m_pFlowSystem)
  2833.                         {
  2834.                                 m_pFlowSystem->Update();
  2835.                         }
  2836.                 }
  2837.  
  2838.                 if (gEnv->pFlashUI)
  2839.                 {
  2840.                         gEnv->pFlashUI->UpdateFG();
  2841.                 }
  2842.  
  2843.                 gEnv->pMovieSystem->ControlCapture();
  2844.  
  2845.                 // if the Game had been paused and is now unpaused, don't update viewsystem until next frame
  2846.                 // if the Game had been unpaused and is now paused, don't update viewsystem until next frame
  2847.                 if (m_pViewSystem)
  2848.                 {
  2849.                         const bool useDeferredViewSystemUpdate = m_pViewSystem->UseDeferredViewSystemUpdate();
  2850.                         if (!useDeferredViewSystemUpdate)
  2851.                         {
  2852.                                 if (!bGameIsPaused && !bGameWasPaused) // don't update view if paused
  2853.                                         m_pViewSystem->Update(min(frameTime, 0.1f));
  2854.                         }
  2855.                 }
  2856.         }
  2857.  
  2858.         m_pActionMapManager->Update();
  2859.  
  2860.         m_pForceFeedBackSystem->Update(frameTime);
  2861.  
  2862.         if (m_pPhysicsQueues)
  2863.         {
  2864.                 m_pPhysicsQueues->Update(frameTime);
  2865.         }
  2866.  
  2867.         if (!bGameIsPaused)
  2868.         {
  2869.                 if (m_pItemSystem)
  2870.                         m_pItemSystem->Update();
  2871.  
  2872.                 if (m_pMaterialEffects)
  2873.                         m_pMaterialEffects->Update(frameTime);
  2874.  
  2875.                 if (m_pBreakableGlassSystem)
  2876.                         m_pBreakableGlassSystem->Update(frameTime);
  2877.  
  2878.                 if (m_pDialogSystem)
  2879.                         m_pDialogSystem->Update(frameTime);
  2880.  
  2881.                 if (m_pVehicleSystem)
  2882.                         m_pVehicleSystem->Update(frameTime);
  2883.  
  2884.                 if (m_pCooperativeAnimationManager)
  2885.                         m_pCooperativeAnimationManager->Update(frameTime);
  2886.         }
  2887.  
  2888.         if (gEnv->pRenderer)
  2889.         {
  2890.                 m_pColorGradientManager->UpdateForThisFrame(gEnv->pTimer->GetFrameTime());
  2891.         }
  2892.  
  2893.         CRConServerListener::GetSingleton().Update();
  2894.         CSimpleHttpServerListener::GetSingleton().Update();
  2895.  
  2896. #if !defined(_RELEASE)
  2897.         CRealtimeRemoteUpdateListener::GetRealtimeRemoteUpdateListener().Update();
  2898. #endif //_RELEASE
  2899.  
  2900.         if (!(updateFlags & ESYSUPDATE_EDITOR))
  2901.         {
  2902. #ifdef ENABLE_LW_PROFILERS
    </