EContextEstablishTaskResult OnStep( SContextEstablishState& state ) { // check our game rules have been registered if (CCryAction::GetCryAction()->GetGameContext()->GetRequestedGameRules().empty()) { GameWarning("SendGameRules: No game rules set"); return eCETR_Failed; } if (CCryAction::GetCryAction()->GetGameContext()->GetLevelName().empty()) { GameWarning("SendGameRules: no level name set"); return eCETR_Failed; } uint16 id = ~uint16(0); // game rules can be set via an alias, if we pass the alias into ClassIdFromName it will fail and disconnect the client, so we lookup the proper name here IGameRulesSystem *pGameRulesSystem = CCryAction::GetCryAction()->GetIGameRulesSystem(); const char *gameRulesName = pGameRulesSystem->GetGameRulesName(CCryAction::GetCryAction()->GetGameContext()->GetRequestedGameRules()); if (!gameRulesName || !m_pRep->ClassIdFromName(id, string(gameRulesName)) || id == (uint16)(~uint16(0))) { GameWarning( "Cannot find rules %s in network class registry", CCryAction::GetCryAction()->GetGameContext()->GetRequestedGameRules().c_str() ); return eCETR_Failed; } // called on the server, we should send any information about the // game type that we need to SSendableHandle * pWaitFor = 0; int nWaitFor = 0; if (m_pWaitFor && !m_pWaitFor->empty()) { pWaitFor = &*m_pWaitFor->begin(); nWaitFor = m_pWaitFor->size(); } state.pSender->AddSendable( new CSimpleNetMessage<SGameTypeParams>(SGameTypeParams(id, CCryAction::GetCryAction()->GetGameContext()->GetLevelName(), CCryAction::GetCryAction()->GetGameContext()->HasContextFlag(eGSF_ImmersiveMultiplayer)), CGameClientChannel::SetGameType), nWaitFor, pWaitFor, NULL ); return eCETR_Ok; }
//------------------------------------------------------------------------ void CGameRulesManager::Init() { XmlNodeRef root = gEnv->pSystem->LoadXmlFromFile( GAMERULES_DEFINITIONS_XML_PATH ); if (root) { if (!stricmp(root->getTag(), "Modes")) { IGameRulesSystem *pGameRulesSystem = g_pGame->GetIGameFramework()->GetIGameRulesSystem(); int numModes = root->getChildCount(); for (int i = 0; i < numModes; ++ i) { XmlNodeRef modeXml = root->getChild(i); if (!stricmp(modeXml->getTag(), "GameMode")) { const char *modeName; if (modeXml->getAttr("name", &modeName)) { pGameRulesSystem->RegisterGameRules(modeName, "GameRules"); SGameRulesData gameRulesData; int numModeChildren = modeXml->getChildCount(); for (int j = 0; j < numModeChildren; ++ j) { XmlNodeRef modeChildXml = modeXml->getChild(j); const char *nodeTag = modeChildXml->getTag(); if (!stricmp(nodeTag, "Alias")) { const char *alias; if (modeChildXml->getAttr("name", &alias)) { pGameRulesSystem->AddGameRulesAlias(modeName, alias); } } else if (!stricmp(nodeTag, "LevelLocation")) { const char *path; if (modeChildXml->getAttr("path", &path)) { pGameRulesSystem->AddGameRulesLevelLocation(modeName, path); } } else if (!stricmp(nodeTag, "Rules")) { const char *path; if (modeChildXml->getAttr("path", &path)) { gameRulesData.m_rulesXMLPath = path; } } else if( !stricmp(nodeTag, "DefaultHudState")) { const char *name; if (modeChildXml->getAttr("name", &name)) { gameRulesData.m_defaultHud = name; } } } // Check if we're a team game if (!gameRulesData.m_rulesXMLPath.empty()) { XmlNodeRef rulesXml = gEnv->pSystem->LoadXmlFromFile( gameRulesData.m_rulesXMLPath.c_str() ); if (rulesXml) { XmlNodeRef teamXml = rulesXml->findChild("Teams"); gameRulesData.m_bIsTeamGame = (teamXml != (IXmlNode*)NULL); } } // Insert gamerule specific data m_rulesData.insert(TDataMap::value_type(modeName, gameRulesData)); } else { CryLogAlways("CGameRulesModulesManager::Init(), invalid 'GameMode' node, requires 'name' attribute"); } } else { CryLogAlways("CGameRulesModulesManager::Init(), invalid xml, expected 'GameMode' node, got '%s'", modeXml->getTag()); } } } else { CryLogAlways("CGameRulesModulesManager::Init(), invalid xml, expected 'Modes' node, got '%s'", root->getTag()); } } }
void CAutoTester::Start(const char *stateSetup, const char *outputPath, bool quitWhenDone) { // If the string has any '#' characters in it (the "new" seperator) then we'll split the string up at those characters... // If not, we'll use '!' (the "old" seperator) char breakAtChar = strchr(stateSetup, '#') ? '#' : '!'; CryLogAlways("CAutoTester::Start() stateSetup=\"%s\" outputPath=\"%s\" seperator=\"%c\"", stateSetup, outputPath, breakAtChar); assert(!m_started); m_started=true; m_outputPath=outputPath; m_quitWhenDone = quitWhenDone; const char *str=stateSetup; // .dll hell stops simple access to memReplay functionality so can't look for running -memReplay // memReplay commands all early exit if they fail anyways gEnv->pConsole->ExecuteString("memReplayDumpSymbols"); #define MAX_TOKEN_LEN 128 char tokenName[MAX_TOKEN_LEN]; char valueName[MAX_TOKEN_LEN]; bool success; memset(&m_stateData, 0, sizeof(m_stateData)); success = GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar); assert (m_state == ATEST_STATE_NONE); if (success && stricmp(tokenName, "state") == 0) { m_state = FindStateFromStr(valueName); cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName)); CryLogAlways("CAutoTester::Start initializing state (name='%s', id=%d, %s)", valueName, m_state, (m_state == ATEST_STATE_NONE) ? "invalid" : "valid"); DesignerWarning (m_state != ATEST_STATE_NONE, "'%s' is not the name of an auto-test state", valueName); // If anything needs to default to something non-zero, set it here... switch (m_state) { case ATEST_STATE_TEST_PERFORMANCE: m_stateData.testPerformance.m_subState = CAutoTester::k_testPerformance_substate_ingame; break; } // Read each parameter... while (GetParam(&str, tokenName, MAX_TOKEN_LEN, valueName, MAX_TOKEN_LEN, breakAtChar)) { bool paramUsed = false; if (stricmp(tokenName, "outputName") == 0) { cry_strncpy(m_includeThisInFileName, valueName, sizeof(m_includeThisInFileName)); CryLogAlways("CAutoTester::Start has set output name to '%s'", m_includeThisInFileName); m_createVerboseFilename=false; paramUsed = true; } else { switch (m_state) { case ATEST_STATE_TEST_NUM_CLIENTS: if (stricmp(tokenName, "timeToRun") == 0) { m_stateData.testNumClients.m_timeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "numClients") == 0) { m_stateData.testNumClients.m_numClientsExpected = atoi(valueName); paramUsed = true; } break; case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE: if (stricmp(tokenName, "timeToRunEachLevel") == 0) { m_stateData.testNumClientsRotate.m_levelTimeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "numClients") == 0) { m_stateData.testNumClientsRotate.m_numClientsExpected = atoi(valueName); paramUsed = true; } else if (stricmp(tokenName, "timeToRunFirstLevel") == 0) { m_stateData.testNumClientsRotate.m_firstLevelTimeOut = (float)atof(valueName); paramUsed = true; } break; #if ENABLE_FEATURE_TESTER case ATEST_STATE_TEST_FEATURES: if (stricmp(tokenName, "rules") == 0) { CryLogAlways ("CAutoTester::Start executing 'sv_gamerules %s'", valueName); gEnv->pConsole->ExecuteString(string().Format("sv_gamerules %s", valueName)); paramUsed = true; } else if (stricmp(tokenName, "level") == 0) { IGameRulesSystem * gameRulesSystem = gEnv->pGame->GetIGameFramework()->GetIGameRulesSystem(); const char * sv_gamerules = gEnv->pConsole->GetCVar("sv_gamerules")->GetString(); const char * fullGameRulesName = gameRulesSystem->GetGameRulesName(sv_gamerules); bool isMultiPlayerMode = (fullGameRulesName && strcmp(fullGameRulesName, "SinglePlayer") != 0); const char * additionalParams = isMultiPlayerMode ? " s nb" : ""; if (gEnv->bMultiplayer != isMultiPlayerMode) { GameWarning("Auto-tester is loading '%s' in mode '%s' while environment is set up for %s", valueName, sv_gamerules, gEnv->bMultiplayer ? "multi-player" : "single-player"); } CryLogAlways ("CAutoTester::Start executing 'map %s%s' (mode is '%s' i.e. '%s' so isMultiPlayer=%d)", valueName, additionalParams, sv_gamerules, fullGameRulesName, isMultiPlayerMode); if (isMultiPlayerMode) { gEnv->pConsole->ExecuteString("net_setonlinemode lan"); } gEnv->pConsole->ExecuteString(string().Format("map %s%s", valueName, additionalParams)); paramUsed = true; } else if (stricmp(tokenName, "set") == 0) { cry_strncpy(m_stateData.testRunFeatureTests.m_setNames, valueName, sizeof(m_stateData.testRunFeatureTests.m_setNames)); paramUsed = true; } else if (stricmp(tokenName, "file") == 0) { cry_strncpy(m_stateData.testRunFeatureTests.m_loadFileName, valueName, sizeof(m_stateData.testRunFeatureTests.m_loadFileName)); paramUsed = true; } break; #endif case ATEST_STATE_TEST_PERFORMANCE: if (stricmp(tokenName, "configFile") == 0) { cry_strncpy(m_stateData.testPerformance.m_configFile, valueName, 256); //m_stateData.testPerformance.m_configFile = valueName; CryLogAlways ("CAutoTester::Start configFile set '%s'", valueName); paramUsed = true; } else if (stricmp(tokenName, "timeToRun") == 0) { m_stateData.testPerformance.m_timeOut = (float)atof(valueName); paramUsed = true; } else if (stricmp(tokenName, "delayToStart") == 0) { m_stateData.testPerformance.m_delayToStart = (float)atof(valueName); paramUsed = true; } break; } DesignerWarning(paramUsed, "Unexpected key/value pair '%s'='%s' in %s setup string!", tokenName, valueName, s_autoTesterStateNames[m_state]); } } // All parameters have been read... now finish initialization switch (m_state) { case ATEST_STATE_TEST_NUM_CLIENTS_LEVEL_ROTATE: { if (m_stateData.testNumClientsRotate.m_firstLevelTimeOut == 0) { CryLogAlways("no timeToRunFirstLevel set, setting to timeToRunEachLevel=%d", (int)m_stateData.testNumClientsRotate.m_levelTimeOut); m_stateData.testNumClientsRotate.m_firstLevelTimeOut = m_stateData.testNumClientsRotate.m_levelTimeOut; } float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds(); m_stateData.testNumClientsRotate.m_nextTimeOut = timeSeconds + m_stateData.testNumClientsRotate.m_firstLevelTimeOut; // level rotation is setup with +sv_levelrotation levelrotation.xml and also -root to override looking in the profile dir gEnv->pConsole->ExecuteString("g_nextlevel"); // has to be a better way of doing this break; } case ATEST_STATE_TEST_FEATURES: #if ENABLE_FEATURE_TESTER m_writeResultsCompleteTestCasePass = true; if (m_stateData.testRunFeatureTests.m_loadFileName[0]) { gEnv->pConsole->ExecuteString(string().Format("ft_load %s", m_stateData.testRunFeatureTests.m_loadFileName)); } if (m_stateData.testRunFeatureTests.m_setNames[0]) { CFeatureTester::GetInstance()->InformAutoTesterOfResults(this); gEnv->pConsole->ExecuteString(string().Format("ft_runAll %s", m_stateData.testRunFeatureTests.m_setNames)); } #else DesignerWarning(false, "Feature tester is not included in this build!"); #endif break; } } else { CRY_ASSERT_MESSAGE(0, string().Format("CAutoTester::Start() failed to find state at start in %s", stateSetup)); } // TODO will maybe need to load in the existing file if we want all tests in the same file... junit/bamboo should cope with each test in a different file? }