//------------------------------------------------------------------------ bool CPlayerProfileImplConsole::SaveProfile(SUserEntry* pEntry, CPlayerProfile* pProfile, const char* name, bool initialSave, int /*reason = ePR_All*/) { IPlatformOS *os = gEnv->pSystem->GetPlatformOS(); // save the profile into a specific location // check if it's a valid filename if (IsValidFilename(name) == false) return false; string path; InternalMakeFSPath(pEntry, name, path); XmlNodeRef rootNode = GetISystem()->CreateXmlNode(PROFILE_ROOT_TAG); rootNode->setAttr(PROFILE_NAME_TAG, name); CSerializerXML serializer(rootNode, false); pProfile->SerializeXML(&serializer); XmlNodeRef attributes = serializer.GetSection(CPlayerProfileManager::ePPS_Attribute); XmlNodeRef actionMap = serializer.GetSection(CPlayerProfileManager::ePPS_Actionmap); if(!rootNode->findChild("Attributes")) rootNode->addChild(attributes); if(!rootNode->findChild("ActionMaps")) rootNode->addChild(actionMap); return SaveXMLFile(path+"profile.xml", rootNode); }
////////////////////////////////////////////////////////////////////////// // // Allows the game code to write game-specific data into the minimap xml // file on level export. Currently used to export data to StatsTool // ////////////////////////////////////////////////////////////////////////// bool CEditorGame::GetAdditionalMinimapData(XmlNodeRef output) { string classes = g_pGameCVars->g_telemetryEntityClassesToExport; if(!classes.empty()) { // additional data relating to StatsTool XmlNodeRef statsNode = output->findChild("StatsTool"); if(!statsNode) { statsNode = GetISystem()->CreateXmlNode("StatsTool"); output->addChild(statsNode); } else { statsNode->removeAllChilds(); } // first build a list of entity classes from the cvar std::vector<IEntityClass*> interestingClasses; int curPos = 0; string currentClass = classes.Tokenize(",",curPos); IEntitySystem* pES = GetISystem()->GetIEntitySystem(); if(IEntityClassRegistry* pClassReg = pES->GetClassRegistry()) { while (!currentClass.empty()) { if(IEntityClass* pClass = pClassReg->FindClass(currentClass.c_str())) { interestingClasses.push_back(pClass); } currentClass = classes.Tokenize(",",curPos); } } // now iterate through all entities and save the ones which match the classes if(interestingClasses.size() > 0) { IEntityItPtr it = pES->GetEntityIterator(); while(IEntity* pEntity = it->Next()) { if(stl::find(interestingClasses, pEntity->GetClass())) { XmlNodeRef entityNode = GetISystem()->CreateXmlNode("Entity"); statsNode->addChild(entityNode); entityNode->setAttr("class", pEntity->GetClass()->GetName()); Vec3 pos = pEntity->GetWorldPos(); entityNode->setAttr("x", pos.x); entityNode->setAttr("y", pos.y); entityNode->setAttr("z", pos.z); } } } } return true; }
static void SaveToXML(const XmlNodeRef& n, const char* name, const TTimeStampedData<T>& data) { XmlNodeRef v = gEnv->pSystem->CreateXmlNode("values"); v->setAttr("name", name); for(int i=0;i<data.m_data.size(); ++i) { XmlNodeRef c = gEnv->pSystem->CreateXmlNode("value"); SaveToXML(c, "time", data.m_data[i].first); T::SaveToXML(c, "", data.m_data[i].second); v->addChild(c); } n->addChild(v); }
bool CCheckpointSystem::SaveExternalEntity(EntityId id) { //this function allows external logic (flowgraph) to save specific entities if(!CHECKPOINT_SAVE_XML_NODE) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Tried writing external entity %i while savegame was not open.", (int)id); return false; } //find entity and access external section IEntity *pEntity = gEnv->pEntitySystem->GetEntity(id); if(pEntity) { XmlNodeRef externalEntities = CHECKPOINT_SAVE_XML_NODE->findChild(EXTERNAL_ENTITIES_SECTION); if(!externalEntities) { externalEntities = GetISystem()->CreateXmlNode(EXTERNAL_ENTITIES_SECTION); CHECKPOINT_SAVE_XML_NODE->addChild(externalEntities); } IActor *pActor = CCryAction::GetCryAction()->GetIActorSystem()->GetActor(pEntity->GetId()); if(pActor) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "The actor %s is additionally saved as external entity.", pEntity->GetName()); } //create entity data char entityId[16]; _snprintf(entityId, sizeof(entityId), "%s%i", "id", id); XmlNodeRef nextEntity = GetISystem()->CreateXmlNode(entityId); if(nextEntity) { nextEntity->setAttr("id", pEntity->GetId()); nextEntity->setAttr("name", pEntity->GetName()); //save active / hidden nextEntity->setAttr("active", pEntity->IsActive()); nextEntity->setAttr("hidden", pEntity->IsHidden()); //save translation and rotation (complete tm matrix for simplicity) SerializeWorldTM(pEntity, nextEntity, true); //add new entity to checkpoint externalEntities->addChild(nextEntity); return true; } return false; } return false; }
void XmlParserImp::onStartElement( const char *tagName,const char **atts ) { XmlNodeRef parent; XmlNodeRef node( tagName ); if (!nodeStack.empty()) { parent = nodeStack.back(); } else { m_root = node; } nodeStack.push_back(node); if (parent) { parent->addChild( node ); } node->setLine( XML_GetCurrentLineNumber( (XML_Parser)m_parser ) ); // Call start element callback. String key,value; int i = 0; while (atts[i] != 0) { node->setAttribute( atts[i],atts[i+1] ); i += 2; } }
void CCheckpointSystem::WriteMetaData(EntityId checkpointId, XmlNodeRef parentNode, SCheckpointData &outMetaData) { XmlNodeRef node = GetISystem()->CreateXmlNode(META_DATA_SECTION); const char *levelName = CCryAction::GetCryAction()->GetLevelName(); CRY_ASSERT(levelName); CryFixedStringT<32> curlevelName = levelName; RepairLevelName(curlevelName); node->setAttr("Version", CHECKPOINT_VERSION_NUMBER); node->setAttr("LevelName", curlevelName.c_str()); node->setAttr("CheckpointId", checkpointId); //write checkpoint name to be independent of entityId IEntity *pCheckpointEntity = gEnv->pEntitySystem->GetEntity(checkpointId); if(pCheckpointEntity) node->setAttr("CheckpointName", pCheckpointEntity->GetName()); else node->setAttr("CheckpointName", "none"); string timeString; GameUtils::timeToString(time(NULL), timeString); node->setAttr("Timestamp", timeString.c_str()); parentNode->addChild(node); //write back metadata for listeners outMetaData.m_checkPointId = checkpointId; outMetaData.m_levelName = levelName; outMetaData.m_saveTime = timeString.c_str(); }
static void SaveToXML(const XmlNodeRef& n, const char* name, const SWeapons& a) { XmlNodeRef w = gEnv->pSystem->CreateXmlNode(name); for(int i = 0; i < a.m_weapons.size(); ++ i) { SWeapon::SaveToXML(w, "weapon", a.m_weapons[i]); } n->addChild(w); }
static void SaveToXML(const XmlNodeRef& n, const char* name, const Vec3& a) { XmlNodeRef v = gEnv->pSystem->CreateXmlNode("vec3"); v->setAttr("name", name); v->setAttr("x", a.x); v->setAttr("y", a.y); v->setAttr("z", a.z); n->addChild(v); }
static void SaveToXML(const XmlNodeRef& n, const char* name, const SWeapon& a) { XmlNodeRef w = gEnv->pSystem->CreateXmlNode(name); ::SaveToXML(w, "name", a.m_name); ::SaveToXML(w, "used", a.m_used); ::SaveToXML(w, "kills", a.m_kills); ::SaveToXML(w, "shots", a.m_shots); ::SaveToXML(w, "hits", a.m_hits); ::SaveToXML(w, "reloads", a.m_reloads); ::SaveToXML(w, "damage", a.m_damage ); n->addChild(w); }
/// Runs all registered tests (if they meet their dependencies) void CFeatureTestMgr::RunAll() { // Writing the list of the active registered tests. // This can be useful to later check, when a crash occurs, // which tests were executed and which are skipped // (We will have no valid results for them) { if(m_pAutoTester && !m_testManifestWritten) { XmlNodeRef testManifest = GetISystem()->CreateXmlNode("testManifest"); testManifest->setTag("testmanifest"); CryLogAlways("About to dump out the testmanifest xml..."); for (TFeatureTestVec::iterator iter(m_featureTests.begin()); iter != m_featureTests.end(); ++iter) { FeatureTestState& fTest = *iter; XmlNodeRef testDescrNode = fTest.m_pTest->XmlDescription(); if(testDescrNode) { testManifest->addChild(testDescrNode); } } m_pAutoTester->WriteTestManifest(testManifest); m_testManifestWritten = true; } } if (!IsRunning()) { // Ensure all tests are cleaned up and scheduled to run ResetAllTests(eFTS_Scheduled); if (StartNextTest() || WaitingForScheduledTests()) { CryLog("Running all map feature tests..."); } else { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "No tests available to run!"); } } else { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Tests are already running, can't start more until tests are complete."); } }
void CCheckpointSystem::WriteActorData(XmlNodeRef parentNode) { XmlNodeRef node = GetISystem()->CreateXmlNode(ACTOR_FLAGS_SECTION); //write only data for non-active or hidden actors XmlNodeRef activatedActors = GetISystem()->CreateXmlNode(ACTIVATED_ACTORS_SECTION); char buffer[100]; IActorSystem *pActorSystem = CCryAction::GetCryAction()->GetIActorSystem(); IActorIteratorPtr it = pActorSystem->CreateActorIterator(); while (IActor *pActor = it->Next()) { IEntity *pEntity = pActor->GetEntity(); if(!pEntity->IsHidden() && pEntity->IsActive()) { EntityId id = pEntity->GetId(); const char *name = pEntity->GetName(); //we have to rely on names, since Id's change on level reexport _snprintf(buffer, sizeof(buffer), "%s%i", "id", id); activatedActors->setAttr(buffer, name); } } node->addChild(activatedActors); parentNode->addChild(node); }
void CCheckpointSystem::WriteGameTokens(XmlNodeRef parentNode) { //create serialization writer XmlNodeRef node = GetISystem()->CreateXmlNode(GAMETOKEN_SECTION); IXmlSerializer *pSerializer = GetISystem()->GetXmlUtils()->CreateXmlSerializer(); ISerialize *pWriter = pSerializer->GetWriter(node); //get serialization data TSerialize ser = TSerialize(pWriter); IGameTokenSystem *pTokenSystem = CCryAction::GetCryAction()->GetIGameTokenSystem(); pTokenSystem->Serialize(ser); //add to parent node parentNode->addChild(node); pSerializer->Release(); }
XmlNodeRef cloneXmlNodeFrom(xml_node<>* xmlnode) { XmlNodeRef node = CreateXmlNode(xmlnode->name()); for (xml_attribute<>* attr = xmlnode->first_attribute(); attr; attr = attr->next_attribute()) { node->setAttrText(attr->name(), attr->value()); } for (xml_node<>* subNode = xmlnode->first_node(); subNode; subNode = subNode->next_sibling()) { XmlNodeRef sub = cloneXmlNodeFrom(subNode); node->addChild(sub); } return node; }
bool CCheckpointSystem::SaveXMLNode(XmlNodeRef node, const char *identifier) { if(!identifier || !node) return false; //check whether a checkpoint is currently open if(!CHECKPOINT_SAVE_XML_NODE) { CryWarning(VALIDATOR_MODULE_GAME, VALIDATOR_WARNING, "Tried writing checkpoint section %s while checkpoint was not open.", identifier); return false; } //flag section as being external and save name node->setAttr("external", identifier); //add section to opened file CHECKPOINT_SAVE_XML_NODE->addChild(node); return true; }
bool CStatHelpers::SaveActorAttachments( CActor* pActor ) { if ( IStatsTracker *tracker = pActor->GetStatsTracker() ) if ( const CActorInventory *pInv = pActor->GetActorInventory() ) { XmlNodeRef resNode = GetISystem()->GetXmlUtils()->CreateStatsXmlNode(MULTIPLE_STAT_XML_TAG); for ( int i = 0; i < pInv->GetAttachmentsCount() ; ++i ) { XmlNodeRef childNode = GetISystem()->CreateXmlNode("attachment"); childNode->setAttr( "name", pInv->GetAttachment( i )->GetName() ); childNode->setAttr( "amount", 1 ); resNode->addChild( childNode ); } tracker->StateValue( eSP_Attachments, resNode ); return true; } return false; }
bool CStatHelpers::SaveActorArmor( CActor* pActor ) { if ( IStatsTracker *tracker = pActor->GetStatsTracker() ) if ( const CCharacterEquip *pEquip = pActor->GetCharacterEquip() ) { XmlNodeRef resNode = GetISystem()->GetXmlUtils()->CreateStatsXmlNode(MULTIPLE_STAT_XML_TAG); for ( int i = 0; i < pEquip->GetItemCount(); ++i ) { XmlNodeRef childNode = GetISystem()->CreateXmlNode("part"); childNode->setAttr( "name", pEquip->GetItem( i ) ); childNode->setAttr( "amount", 1 ); resNode->addChild( childNode ); } tracker->StateValue( eSP_Armor, resNode ); return true; } return false; }
// create the xmlnode before passing it in void CAutoTester::CreateTestCase(XmlNodeRef &testCase, const char *testName, bool passed, const char *failedType, const char *failedMessage) { assert(testName); testCase->setTag("testcase"); testCase->setAttr("name", testName ? testName : "NULL"); testCase->setAttr("time", 0); if (!passed) { assert(failedType); assert(failedMessage); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", failedType ? failedType : "NULL"); failedCase->setAttr("message", failedMessage ? failedMessage : "NULL"); testCase->addChild(failedCase); } }
void CGameStats::SaveStats() { if(m_roundStats->m_round) { SGetTime time(m_roundStart); CryFixedStringT<128> timeStr; time_t ltime; ::time( <ime ); tm *today = localtime( <ime ); strftime(timeStr.m_str, timeStr.MAX_SIZE, "%y-%m-%d_%H%M%S", today); XmlNodeRef root = gEnv->pSystem->CreateXmlNode("round"); root->setAttr("round", m_roundStats->m_round); SRoundStats::SaveToXML(root, "", *m_roundStats.get()); for(PlayerStatsMap::iterator it = m_playerMap.begin(), eit = m_playerMap.end(); it != eit; ++it) { for( SPlayerInfo::TStatsVct::iterator si = it->second.stats.begin(); si < it->second.stats.end(); ++si ) { it->second.stats.back()->End(time); XmlNodeRef plr = gEnv->pSystem->CreateXmlNode("player"); if(IEntity *p = gEnv->pEntitySystem->GetEntity(it->first)) { plr->setAttr("id", p->GetId()); if ( IActor* pAct = m_pGameFramework->GetIActorSystem()->GetActor(p->GetId()) ) { int profile = m_pGameFramework->GetNetChannel(pAct->GetChannelId())->GetProfileId(); plr->setAttr("profile", profile); } } plr->setAttr("name", it->second.name); plr->setAttr("team", it->second.team); plr->setAttr("spectator", it->second.spectator); SPlayerStats::SaveToXML(plr, "", *(si->get())); root->addChild(plr); } } root->saveToFile(string().Format("%s/StatsLogs/Round_%s.xml", gEnv->pCryPak->GetAlias("%USER%"), timeStr.c_str())); } }
void CEntityAttributesProxy::SerializeXML(XmlNodeRef &entityNodeXML, bool loading) { if(loading == true) { if(XmlNodeRef attributesNodeXML = entityNodeXML->findChild("Attributes")) { SEntityAttributesSerializer serializer(m_attributes); Serialization::LoadXmlNode(serializer, attributesNodeXML); } } else { if(!m_attributes.empty()) { SEntityAttributesSerializer serializer(m_attributes); if(XmlNodeRef attributesNodeXML = Serialization::SaveXmlNode(serializer, "Attributes")) { entityNodeXML->addChild(attributesNodeXML); } } } }
void CAutoTester::AddSimpleTestCase(const char * groupName, const char * testName, float duration, const char * failureReason, const char * owners) { bool passed = true; XmlNodeRef testCase = GetISystem()->CreateXmlNode(); testCase->setTag("testcase"); testCase->setAttr("name", testName); if (owners) { testCase->setAttr("owners", owners); } if (duration >= 0.f) { testCase->setAttr("time", duration); } // Set whatever other attributes are useful here! if (failureReason == NULL || failureReason[0] == '\0') { CryLogAlways ("CAutoTester::AddSimpleTestCase() Group '%s' test '%s' passed!", groupName, testName); testCase->setAttr("status", "run"); } else { CryLogAlways ("CAutoTester::AddSimpleTestCase() Group '%s' test '%s' failed: %s", groupName, testName, failureReason); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", "TestCaseFailed"); failedCase->setAttr("message", failureReason); testCase->addChild(failedCase); passed = false; } AddTestCaseResult(string().Format("%s: %s", m_includeThisInFileName, groupName ? groupName : "No group name specified"), testCase, passed); }
void CAntiCheatManager::ProcessFlagActivity(TCheatType type, uint16 channelId, const float *params, int numParams, const char * pDescription, XmlNodeRef additionalXmlData) { SCheatType &cheat = m_cheats[type]; XmlNodeRef incidentXML; float fInfractionsSeverity = 0.0f; int nMaxConfidence = 0, nMaxInfractionConfidence = 0; typedef std::vector<const SCheatAction*> TCheatActionPtrList; TCheatActionPtrList actionsToTake; EDisconnectionCause kickReason = eDC_Kicked; for (std::vector<SCheatAction>::iterator itAction = cheat.actions.begin(); itAction != cheat.actions.end(); ++itAction) { bool meetsConditions = true; for (std::vector<SCheatCondition>::const_iterator itCondition = itAction->conditions.begin(); itCondition != itAction->conditions.end(); ++itCondition) { assert(itCondition->paramNum <= numParams); float paramValue = params[itCondition->paramNum-1]; meetsConditions = MeetsCondition(itCondition->op, paramValue, itCondition->value); if (!meetsConditions) { break; } } if (meetsConditions) { actionsToTake.push_back(&(*itAction)); if(incidentXML == NULL) { incidentXML = CreateIncidentXML(channelId, type, params, numParams, pDescription); if(additionalXmlData != NULL && incidentXML != NULL) incidentXML->addChild(additionalXmlData); } } if(itAction->action == eCA_Global_Ban) { kickReason = GetBanKickType(channelId); } } bool bDoRemoteLog = false; for(TCheatActionPtrList::const_iterator itActionPtr = actionsToTake.begin(); itActionPtr != actionsToTake.end(); ++itActionPtr) { const SCheatAction * actionPtr = *itActionPtr; nMaxConfidence = max(actionPtr->confidence, nMaxConfidence); switch (actionPtr->action) { case eCA_Log: //The presence of this action will cause the incident to be logged, we don't want to add // any more output as it won't provide any more data break; case eCA_Log_Remote: bDoRemoteLog = true; break; case eCA_Infraction: { fInfractionsSeverity += actionPtr->severity; nMaxInfractionConfidence = max(actionPtr->confidence, nMaxInfractionConfidence); } break; case eCA_Kick: CheatLogAction(incidentXML, eCA_Kick, actionPtr->confidence); KickPlayer(channelId, kickReason, actionPtr->confidence); break; case eCA_Kick_Delayed: CheatLogAction(incidentXML, eCA_Kick_Delayed, actionPtr->confidence); KickPlayerDelayed(channelId, kickReason, actionPtr->confidence); break; case eCA_Ban: CheatLogAction(incidentXML, eCA_Ban, actionPtr->confidence); BanPlayer_Internal(channelId, actionPtr->banTimeout, actionPtr->confidence); break; case eCA_Global_Ban: break; case eCA_Dev_CheatDetected: { #if defined(DEV_CHEAT_HANDLING) CheatLogAction(incidentXML, eCA_Dev_CheatDetected, actionPtr->confidence); stack_string paramsString; CAntiCheatManager::GenerateMessageString(paramsString, params, numParams, pDescription); paramsString.append(" "); paramsString.append(s_cheatTypeNames[type]); HandleDevCheat(channelId, paramsString); #endif break; } } } //If multiple infractions have been triggered by the parameters, we want to log if(fInfractionsSeverity > 0.0f) { XmlNodeRef actionXml = CheatLogAction(incidentXML, eCA_Infraction, nMaxInfractionConfidence); RegisterInfraction(actionXml, channelId, type, fInfractionsSeverity); } if(incidentXML) { CheatLogInternalXml(incidentXML); } }
bool CEditorGame::BuildEntitySerializationList(XmlNodeRef output) { if(!output) return false; typedef std::vector<IFlowGraph*> TFGVector; TSerializationData entityData; // all entities TFGVector flowGraphs; // all flowgraphs // build the all-entity list, and keep a record of those entities // which have a flowgraph attached IEntityIt* pIt = gEnv->pEntitySystem->GetEntityIterator(); while(IEntity* pEntity = pIt->Next()) { IEntityFlowGraphProxy* pFGProxy = static_cast<IEntityFlowGraphProxy*>(pEntity->GetProxy(ENTITY_PROXY_FLOWGRAPH)); if(pFGProxy) { flowGraphs.push_back(pFGProxy->GetFlowGraph()); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraphContainer); } if (!stricmp(pEntity->GetClass()->GetName(), "Constraint")) { MarkEntityForSerialize(entityData, pEntity, eST_Class); float constraintRadius = -FLT_MAX; if (IScriptTable* entityTable = pEntity->GetScriptTable()) { SmartScriptTable props; if (entityTable->GetValue("Properties", props)) props->GetValue("radius", constraintRadius); } if (constraintRadius > 0.0f) { const Vec3 boxMin = pEntity->GetWorldPos() - Vec3(constraintRadius + 0.05f); const Vec3 boxMax = pEntity->GetWorldPos() + Vec3(constraintRadius + 0.05f); IPhysicalEntity** nearbyEntities = 0; if (size_t entityCount = gEnv->pPhysicalWorld->GetEntitiesInBox(boxMin, boxMax, nearbyEntities, ent_all)) { for (size_t i = 0; i < entityCount; ++i) { if (IEntity* nearbyEntity = gEnv->pEntitySystem->GetEntityFromPhysics(nearbyEntities[i])) MarkEntityForSerialize(entityData, nearbyEntity, eST_ConstraintNeighbour); } } } else { CryLogAlways("Failed to find a value radius property for constraint '%s'. " "Serialization for this constraint might not work.", pEntity->GetName()); } } else if(ShouldSaveEntityClass(pEntity)) // some classes should always be saved MarkEntityForSerialize(entityData, pEntity, eST_Class); } // for each FG, mark all entities referenced as needing saving for(TFGVector::const_iterator it = flowGraphs.begin(); it != flowGraphs.end(); ++it) { if(!*it) continue; IFlowNodeIteratorPtr nodeIt = (*it)->CreateNodeIterator(); TFlowNodeId nodeId = 0; while(IFlowNodeData* pNode = nodeIt->Next(nodeId)) { EntityId nodeEntity = (*it)->GetEntityId(nodeId); if(nodeEntity != 0) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(nodeEntity); MarkEntityForSerialize(entityData, pEntity, eST_FlowGraph); } } } // now do the same for entities moved by trackview for(int i=0; i<gEnv->pMovieSystem->GetNumSequences(); ++i) { IAnimSequence* pSeq = gEnv->pMovieSystem->GetSequence(i); int nodeCount = pSeq->GetNodeCount(); for(int j=0; j<nodeCount; ++j) { IAnimNode* pNode = pSeq->GetNode(j); if(pNode) { IEntity* pEntity = pNode->GetEntity(); if(pEntity && ShouldSaveTrackViewEntityClass(pEntity)) { MarkEntityForSerialize(entityData, pEntity, eST_TrackView); } if(EntityGUID* guid = pNode->GetEntityGuid()) { EntityId id = gEnv->pEntitySystem->FindEntityByGuid(*guid); if(id != 0) { IEntity* pEntity2 = gEnv->pEntitySystem->GetEntity(id); MarkEntityForSerialize(entityData, pEntity2, eST_TrackView); } } } } } // now check entity links: any entity linked to or from a serialized // entity must also be serialized for(TSerializationData::iterator it = entityData.begin(), end = entityData.end(); it != end; ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); assert(pEntity); IEntityLink* pLink = pEntity->GetEntityLinks(); while(pLink) { IEntity* pLinkedEntity = gEnv->pEntitySystem->GetEntity(pLink->entityId); assert(pLinkedEntity); MarkEntityForSerialize(entityData, pLinkedEntity, eST_Linked); pLink = pLink->next; } } // output the final file, plus debug info #if SERIALIZATION_EXPORT_DEBUG int saveCount = 0; int totalCount = 0; int fgCount = 0; int fgRefCount = 0; int classCount = 0; int tvCount = 0; int childCount = 0; int parentCount = 0; int linkCount = 0; int fgUnique = 0; int fgRefUnique = 0; int classUnique = 0; int tvUnique = 0; int linkUnique = 0; typedef std::map<string, int> TClassSaveInfo; TClassSaveInfo classesNotSaved; TClassSaveInfo classesSaved; #endif output->setTag("EntitySerialization"); for(TSerializationData::const_iterator it = entityData.begin(); it != entityData.end(); ++it) { IEntity* pEntity = gEnv->pEntitySystem->GetEntity(it->first); #if SERIALIZATION_EXPORT_DEBUG ++totalCount; string reasons = "Saving: "; #endif if(it->second != eST_NotSerialized) { XmlNodeRef child = output->createNode("Entity"); child->setAttr("id", it->first); //child->setAttr("class", pEntity->GetClass()->GetName()); // debug check //child->setAttr("name", pEntity->GetName()); // debug check output->addChild(child); #if SERIALIZATION_EXPORT_DEBUG classesSaved[pEntity->GetClass()->GetName()]++; ++saveCount; if(it->second & eST_FlowGraphContainer) { reasons += "FG Container; "; ++fgCount; } if(it->second & eST_FlowGraph) { reasons += "FG reference; "; ++fgRefCount; } if(it->second & eST_Class) { reasons += "Class; "; ++classCount; } if(it->second & eST_TrackView) { reasons += "Trackview; "; ++tvCount; } if(it->second & eST_Child) { reasons += "Child; "; ++childCount; } if(it->second & eST_Parent) { reasons += "Parent; "; ++parentCount; } if(it->second & eST_Linked) { reasons += "Linked; "; ++linkCount; } // unique counts (things added as a result of only one condition) switch(it->second) { case eST_FlowGraph: ++fgRefUnique; break; case eST_FlowGraphContainer: ++fgUnique; break; case eST_Class: ++classUnique; break; case eST_TrackView: ++tvUnique; break; case eST_Linked: ++linkUnique; break; default: break; } } else { reasons = "Not saving"; classesNotSaved[pEntity->GetClass()->GetName()]++; } CryLogAlways("Entity %s (%d, class %s) : %s", pEntity->GetName(), it->first, pEntity->GetClass()->GetName(), reasons.c_str()); #endif } }
XmlNodeRef CAudioSystemEditor_wwise::CreateXMLNodeFromConnection(const TConnectionPtr pConnection, const EACEControlType eATLControlType) { const IAudioSystemControl* pControl = GetControl(pConnection->GetID()); if (pControl) { switch (pControl->GetType()) { case AudioControls::eWCT_WWISE_SWITCH: case AudioControls::eWCT_WWISE_SWITCH_GROUP: case AudioControls::eWCT_WWISE_GAME_STATE: case AudioControls::eWCT_WWISE_GAME_STATE_GROUP: { const IAudioSystemControl* pParent = pControl->GetParent(); if (pParent) { XmlNodeRef pSwitchNode = GetISystem()->CreateXmlNode(TypeToTag(pParent->GetType())); pSwitchNode->setAttr("wwise_name", pParent->GetName()); XmlNodeRef pStateNode = pSwitchNode->createNode("WwiseValue"); pStateNode->setAttr("wwise_name", pControl->GetName()); pSwitchNode->addChild(pStateNode); return pSwitchNode; } } break; case AudioControls::eWCT_WWISE_RTPC: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); if (eATLControlType == eACET_RTPC) { std::shared_ptr<const CRtpcConnection> pRtpcConnection = std::static_pointer_cast<const CRtpcConnection>(pConnection); if (pRtpcConnection->fMult != 1.0f) { pConnectionNode->setAttr("atl_mult", pRtpcConnection->fMult); } if (pRtpcConnection->fShift != 0.0f) { pConnectionNode->setAttr("atl_shift", pRtpcConnection->fShift); } } else if (eATLControlType == eACET_SWITCH_STATE) { std::shared_ptr<const CStateToRtpcConnection> pStateConnection = std::static_pointer_cast<const CStateToRtpcConnection>(pConnection); pConnectionNode->setAttr("wwise_value", pStateConnection->fValue); } return pConnectionNode; } break; case AudioControls::eWCT_WWISE_EVENT: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); return pConnectionNode; } break; case AudioControls::eWCT_WWISE_AUX_BUS: { XmlNodeRef pConnectionNode; pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); return pConnectionNode; } break; case AudioControls::eWCT_WWISE_SOUND_BANK: { XmlNodeRef pConnectionNode = GetISystem()->CreateXmlNode(TypeToTag(pControl->GetType())); pConnectionNode->setAttr("wwise_name", pControl->GetName()); if (pControl->IsLocalised()) { pConnectionNode->setAttr("wwise_localised", "true"); } return pConnectionNode; } break; } } return nullptr; }
void CAutoTester::WriteResults(TBitfield flags, const string * additionalTestSuiteName, const XmlNodeRef * additionalTestCase) { const int& autotest_enabled = g_pGameCVars->autotest_enabled; if (!autotest_enabled) { return; } //If result generation is skipped, exit early if (autotest_enabled == 2) { if (m_quitWhenDone) { gEnv->pConsole->ExecuteString("quit"); } return; } // test workaround //DesignerWarning(0, "test warning"); // test workaround const char * mapName; string gameRulesName; const char * serverText = ""; const char * dedicatedText = gEnv->IsDedicated() ? "_Dedicated" : ""; CGameRules * rules = g_pGame ? g_pGame->GetGameRules() : NULL; if (rules) { gameRulesName = rules->GetEntity()->GetClass()->GetName(); serverText = gEnv->bServer ? "_Server" : "_Client"; } else { gameRulesName = "FrontEnd"; } if (g_pGame && g_pGame->GetIGameFramework()->GetILevelSystem()->GetCurrentLevel()) { mapName = g_pGame->GetIGameFramework()->GetILevelSystem()->GetCurrentLevel()->GetLevelInfo()->GetName(); } else { mapName = "NoMapLoaded"; } #ifndef _RELEASE CryLogAlways ("CAutoTester::WriteResults(%s): map is '%s', game mode is '%s'", AutoEnum_GetStringFromBitfield(flags, s_writeResultsFlagNames, WriteResultsFlagList_numBits).c_str(), mapName, gameRulesName.c_str()); #endif XmlNodeRef testSuites = GetISystem()->CreateXmlNode("testSuites"); testSuites->setTag("testsuites"); for (TTestSuites::const_iterator it=m_testSuites.begin(); it!=m_testSuites.end(); ++it) { const STestSuite &testSuiteStruct = it->second; int numTests = testSuiteStruct.m_testCases.size(); int numFails = testSuiteStruct.m_numTestCasesFailed; XmlNodeRef testSuite = GetISystem()->CreateXmlNode("AutoTest"); testSuite->setTag("testsuite"); testSuite->setAttr("name", it->first); testSuite->setAttr("LevelName", mapName); testSuite->setAttr("GameRulesName", gameRulesName); if (additionalTestSuiteName && it->first == *additionalTestSuiteName) { CryLog ("Writing additional test case to existing '%s' suite", additionalTestSuiteName->c_str()); ++ numFails; // Assumption here that any additional test data provided is a failure... [TF] ++ numTests; testSuite->addChild(*additionalTestCase); additionalTestSuiteName = NULL; } testSuite->setAttr("tests", numTests); testSuite->setAttr("failures", numFails); testSuite->setAttr("errors", 0); testSuite->setAttr("time", 0); for (size_t i = 0; i < testSuiteStruct.m_testCases.size(); i++) { testSuite->addChild(testSuiteStruct.m_testCases[i]); } testSuites->addChild(testSuite); } if (additionalTestSuiteName) // Still haven't written our additional test case because the suite name didn't match any existing suite... { CryLog ("CAutoTester writing additional test case to unique '%s' suite", additionalTestSuiteName->c_str()); XmlNodeRef testSuite = GetISystem()->CreateXmlNode("AutoTest"); testSuite->setTag("testsuite"); testSuite->setAttr("name", *additionalTestSuiteName); testSuite->setAttr("LevelName", mapName); testSuite->setAttr("GameRulesName", gameRulesName); testSuite->setAttr("tests", 1); testSuite->setAttr("failures", 1); testSuite->setAttr("errors", 0); testSuite->setAttr("time", 0); testSuite->addChild(*additionalTestCase); testSuites->addChild(testSuite); } char mapNameChrs[256]; char gameRulesNameChrs[256]; cry_strncpy(mapNameChrs, mapName, sizeof(mapNameChrs)); cry_strncpy(gameRulesNameChrs, gameRulesName, sizeof(gameRulesNameChrs)); for (int i=0; mapNameChrs[i]; i++) { if (mapNameChrs[i] == '/' || mapNameChrs[i] == ' ') { mapNameChrs[i] = '_'; } } for (int i=0; gameRulesNameChrs[i]; i++) { if (gameRulesNameChrs[i] == '/' || gameRulesNameChrs[i] == ' ') { gameRulesNameChrs[i] = '_'; } } const char * resultsCompleteFailMessage = NULL; if (flags & kWriteResultsFlag_unfinished) { resultsCompleteFailMessage = "Didn't finish all tests!"; } else if (m_testSuites.size() == 0) { resultsCompleteFailMessage = "Ran zero tests!"; } if (resultsCompleteFailMessage || m_writeResultsCompleteTestCasePass) { int numFailures = 0; XmlNodeRef testSuite = GetISystem()->CreateXmlNode("testsuite"); testSuite->setAttr("name", "Are results complete?"); XmlNodeRef unfinishedFailure = GetISystem()->CreateXmlNode("testcase"); if (m_createVerboseFilename) { unfinishedFailure->setAttr("name", string().Format("%s_%s_%s%s%s", m_includeThisInFileName, mapNameChrs, gameRulesNameChrs, dedicatedText, serverText)); } else { unfinishedFailure->setAttr("name", string().Format("%s%s", m_includeThisInFileName, dedicatedText)); } if (resultsCompleteFailMessage) { XmlNodeRef failedCase = GetISystem()->CreateXmlNode("failure"); failedCase->setAttr("type", "Unfinished"); failedCase->setAttr("message", resultsCompleteFailMessage); unfinishedFailure->addChild(failedCase); ++ numFailures; } else { unfinishedFailure->setAttr("status", "run"); } testSuite->setAttr("tests", 1); testSuite->setAttr("errors", 0); testSuite->setAttr("time", 0); testSuite->setAttr("failures", numFailures); testSuite->addChild(unfinishedFailure); testSuites->addChild(testSuite); } string justTheFilename; if (m_createVerboseFilename) { justTheFilename.Format("autotest_%s_%s_%s%s%s.xml", m_includeThisInFileName, mapNameChrs, gameRulesNameChrs, dedicatedText, serverText); // TODO add datestamp if needed } else { // If m_createVerboseFilename is false, then only include things in the filename which WON'T CHANGE between the test starting and ending [TF] justTheFilename.Format("autotest_%s%s.xml", m_includeThisInFileName, dedicatedText); } m_outputPath.Format("../Xml-Reports/%s", justTheFilename.c_str()); #ifndef _RELEASE CryLogAlways ("Outputting test to %s", m_outputPath.c_str()); #endif SaveToValidXmlFile(testSuites, m_outputPath.c_str()); if (flags & kWriteResultsFlag_writeDoneMarkerFile) { XmlNodeRef finished = GetISystem()->CreateXmlNode("Finished"); SaveToValidXmlFile(finished, m_outputPath + ".done"); if (m_quitWhenDone) { gEnv->pConsole->ExecuteString("unload"); gEnv->pConsole->ExecuteString("quit"); } } }
// TODO parameterise and refactor this now its mainly duplicated between the two runs void CAutoTester::UpdateTestNumClients() { if(gEnv->bServer) { IGameFramework *pFramework = gEnv->pGame->GetIGameFramework(); int numChannels = 1; //local channel if(pFramework) { INetNub *pNub = pFramework->GetServerNetNub(); if(pNub) { numChannels = pNub->GetNumChannels(); } } if (numChannels > m_stateData.testNumClients.m_maxNumClientsConnected) { m_stateData.testNumClients.m_maxNumClientsConnected=numChannels; } float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds(); CryWatch("time=%f; numClients=%d; maxNumClients=%d; numClientsExpected=%d", timeSeconds, numChannels, m_stateData.testNumClients.m_maxNumClientsConnected, m_stateData.testNumClients.m_numClientsExpected); if (timeSeconds > m_stateData.testNumClients.m_debugTimer) { m_stateData.testNumClients.m_debugTimer = timeSeconds+2.0f; CryLogAlways("CAutoTester::UpdateTestNumClients() updating time=%f; numClients=%d; maxNumClients=%d; numClientsExpected=%d", timeSeconds, numChannels, m_stateData.testNumClients.m_maxNumClientsConnected, m_stateData.testNumClients.m_numClientsExpected); } if (timeSeconds > m_stateData.testNumClients.m_timeOut) { CryLogAlways("CAutoTester::UpdateTestNumClients() testing num clients and time has expired. numClients=%d; maxNumClients=%d; numClientsExpected=%d", numChannels, m_stateData.testNumClients.m_maxNumClientsConnected, m_stateData.testNumClients.m_numClientsExpected); bool passed=false; string mapName = g_pGame->GetIGameFramework()->GetILevelSystem()->GetCurrentLevel()->GetLevelInfo()->GetName(); string gameRulesName; gameRulesName = g_pGame->GetGameRules()->GetEntity()->GetClass()->GetName(); XmlNodeRef testCase = GetISystem()->CreateXmlNode(); string nameStr; nameStr.Format("Level: %s; gameRules: %s; numClients=%d; timeTested=%.1f seconds", mapName.c_str(), gameRulesName.c_str(), numChannels, m_stateData.testNumClients.m_timeOut); testCase->setTag("testcase"); testCase->setAttr("name", nameStr.c_str()); testCase->setAttr("time", 0); testCase->setAttr("numClients", numChannels); testCase->setAttr("maxNumClientsConnected",m_stateData.testNumClients.m_maxNumClientsConnected); testCase->setAttr("numClientsExpected", m_stateData.testNumClients.m_numClientsExpected); if (numChannels == m_stateData.testNumClients.m_maxNumClientsConnected) { CryLogAlways("CAutoTester::UpdateTestNumClients() testing num clients and time has expired. We have the same number of clients are our maxNumClients %d", numChannels); if (numChannels == m_stateData.testNumClients.m_numClientsExpected) // may want to remove this check as keeping the number that joined should be sufficient { CryLogAlways("CAutoTester::UpdateTestNumClients() testing num clients and time has expired. We have the same number of clients as we expected to have %d", numChannels); testCase->setAttr("status", "run"); passed=true; } else { CryLogAlways("CAutoTester::UpdateTestNumClients() testing num clients and time has expired. We DON'T have the same number of clients %d as we expected to have %d", numChannels, m_stateData.testNumClients.m_numClientsExpected); //testCase->setAttr("status", "failed"); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", "NotEnoughClients"); failedCase->setAttr("message", string().Format("testing num clients and time has expired. We DON'T have the same number of clients %d as we expected to have %d", numChannels, m_stateData.testNumClients.m_numClientsExpected)); testCase->addChild(failedCase); } } else { //testCase->setAttr("status", "failed"); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", "NotEnoughClients"); failedCase->setAttr("message", string().Format("testing num clients and time has expired. We DON'T have the same number of clients %d as we peaked at %d", numChannels, m_stateData.testNumClients.m_maxNumClientsConnected)); testCase->addChild(failedCase); } AddTestCaseResult("Test Clients In Levels", testCase, passed); Stop(); } } }
void CAutoTester::UpdateTestNumClientsLevelRotate() { if(gEnv->bServer) { IGameFramework *pFramework = gEnv->pGame->GetIGameFramework(); int numChannels = 1; //local channel if(pFramework) { INetNub *pNub = pFramework->GetServerNetNub(); if(pNub) { numChannels = pNub->GetNumChannels(); } } if (numChannels > m_stateData.testNumClientsRotate.m_maxNumClientsConnected) { m_stateData.testNumClientsRotate.m_maxNumClientsConnected=numChannels; } float timeSeconds=gEnv->pTimer->GetFrameStartTime().GetSeconds(); CryWatch("time=%f; nextTimeOut=%f; numClients=%d; maxNumClients=%d; numClientsExpected=%d", timeSeconds, m_stateData.testNumClientsRotate.m_nextTimeOut, numChannels, m_stateData.testNumClientsRotate.m_maxNumClientsConnected, m_stateData.testNumClientsRotate.m_numClientsExpected); if (timeSeconds > m_stateData.testNumClientsRotate.m_debugTimer) { m_stateData.testNumClientsRotate.m_debugTimer = timeSeconds+2.0f; CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() updating time=%f; nextTimeOut=%f; numClients=%d; maxNumClients=%d; numClientsExpected=%d", timeSeconds, m_stateData.testNumClientsRotate.m_nextTimeOut, numChannels, m_stateData.testNumClientsRotate.m_maxNumClientsConnected, m_stateData.testNumClientsRotate.m_numClientsExpected); } if (timeSeconds > m_stateData.testNumClientsRotate.m_nextTimeOut) { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() testing num clients and time has expired. numClients=%d; maxNumClients=%d; numClientsExpected=%d", numChannels, m_stateData.testNumClientsRotate.m_maxNumClientsConnected, m_stateData.testNumClientsRotate.m_numClientsExpected); bool passed=false; ILevelRotation *pLevelRotation = g_pGame->GetIGameFramework()->GetILevelSystem()->GetLevelRotation(); string mapName = g_pGame->GetIGameFramework()->GetILevelSystem()->GetCurrentLevel()->GetLevelInfo()->GetName(); string gameRulesName; gameRulesName = g_pGame->GetGameRules()->GetEntity()->GetClass()->GetName(); XmlNodeRef testCase = GetISystem()->CreateXmlNode(); string nameStr; if (m_stateData.testNumClientsRotate.m_levelIndex == 0) { nameStr.Format("%02d/%d) Level: %s; gameRules: %s; numClients=%d; timeTested=%.1f seconds", m_stateData.testNumClientsRotate.m_levelIndex+1, pLevelRotation->GetLength(), mapName.c_str(), gameRulesName.c_str(), numChannels, m_stateData.testNumClientsRotate.m_firstLevelTimeOut); } else { nameStr.Format("%02d/%d) Level: %s; gameRules: %s; numClients=%d; timeTested=%.1f seconds", m_stateData.testNumClientsRotate.m_levelIndex+1, pLevelRotation->GetLength(), mapName.c_str(), gameRulesName.c_str(), numChannels, m_stateData.testNumClientsRotate.m_levelTimeOut); } CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() outputting a test result with these details [%s]", nameStr.c_str()); testCase->setTag("testcase"); testCase->setAttr("name", nameStr.c_str()); testCase->setAttr("time", 0); testCase->setAttr("numClients", numChannels); testCase->setAttr("maxNumClientsConnected",m_stateData.testNumClientsRotate.m_maxNumClientsConnected); testCase->setAttr("numClientsExpected", m_stateData.testNumClientsRotate.m_numClientsExpected); if (numChannels == m_stateData.testNumClientsRotate.m_maxNumClientsConnected) { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() testing num clients and time has expired. We have the same number of clients are our maxNumClients %d", numChannels); if (numChannels == m_stateData.testNumClientsRotate.m_numClientsExpected) // may want to remove this check as keeping the number that joined should be sufficient { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() testing num clients and time has expired. We have the same number of clients as we expected to have %d", numChannels); testCase->setAttr("status", "run"); passed=true; } else { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() testing num clients and time has expired. We DON'T have the same number of clients %d as we expected to have %d", numChannels, m_stateData.testNumClientsRotate.m_numClientsExpected); //testCase->setAttr("status", "failed"); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", "NotEnoughClients"); failedCase->setAttr("message", string().Format("testing num clients and time has expired. We DON'T have the same number of clients %d as we expected to have %d", numChannels, m_stateData.testNumClientsRotate.m_numClientsExpected)); testCase->addChild(failedCase); } } else { //testCase->setAttr("status", "failed"); XmlNodeRef failedCase = GetISystem()->CreateXmlNode(); failedCase->setTag("failure"); failedCase->setAttr("type", "NotEnoughClients"); failedCase->setAttr("message", string().Format("testing num clients and time has expired. We DON'T have the same number of clients %d as we peaked at %d", numChannels, m_stateData.testNumClientsRotate.m_maxNumClientsConnected)); testCase->addChild(failedCase); } AddTestCaseResult("Test Clients In Level Rotation", testCase, passed); Stop(); if (pLevelRotation->GetNext() != 0) { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() has found we're not at the end of the level rotation moving on to the next level - levelIndex=%d; rotation->GetNext()=%d\n", m_stateData.testNumClientsRotate.m_levelIndex+1, pLevelRotation->GetNext()); Restart(); gEnv->pConsole->ExecuteString("g_nextlevel"); // has to be a better way of doing this m_stateData.testNumClientsRotate.m_nextTimeOut = timeSeconds + m_stateData.testNumClientsRotate.m_levelTimeOut; m_stateData.testNumClientsRotate.m_levelIndex++; } else { CryLogAlways("CAutoTester::UpdateTestNumClientsLevelRotate() has found we ARE at the end of the level rotation. Not doing anymore tests\n"); } } } }
XmlNodeRef MakeXmlNodeStruct(const char* str, const behaviac::string& typeNameT) { behaviac::string src = str; //{color=0;id=;type={bLive=false;name=0;weight=0;};} //the first char is '{' //the last char is '}' behaviac::string::size_type posCloseBrackets = behaviac::StringUtils::Private::SkipPairedBrackets(src); BEHAVIAC_ASSERT(posCloseBrackets != behaviac::string::npos); bool bIsStructMember = false; XmlNodeRef xmlNode = CreateXmlNode(typeNameT.c_str()); //{color=0;id=;type={bLive=false;name=0;weight=0;};} //{color=0;id=;type={bLive=false;name=0;weight=0;};transit_points=3:{coordX=0;coordY=0;}|{coordX=0;coordY=0;}|{coordX=0;coordY=0;};} behaviac::string::size_type posBegin = 1; behaviac::string::size_type posEnd = src.find_first_of(';', posBegin); while (posEnd != behaviac::string::npos) { BEHAVIAC_ASSERT(src[posEnd] == ';'); //the last one might be empty if (posEnd > posBegin) { behaviac::string::size_type posEqual = src.find_first_of('=', posBegin); BEHAVIAC_ASSERT(posEqual > posBegin); size_t length = posEqual - posBegin; behaviac::string memmberName = src.substr(posBegin, length); behaviac::string memmberValue; char c = src[posEqual + 1]; if (c != '{') { //to check if it is an array if (IsArrayString(src, posEqual + 1, posEnd)) { length = posEnd - posEqual - 1; memmberValue = src.substr(posEqual + 1, length); } else { length = posEnd - posEqual - 1; memmberValue = src.substr(posEqual + 1, length); } } else { bIsStructMember = true; const char* pStructBegin = src.c_str(); pStructBegin += posEqual + 1; const char* posCloseBrackets_ = behaviac::StringUtils::Private::SkipPairedBrackets(pStructBegin); length = posCloseBrackets_ - pStructBegin + 1; memmberValue = src.substr(posEqual + 1, length); posEnd = posEqual + 1 + length; } if (bIsStructMember) { XmlNodeRef memberNode = MakeXmlNodeStruct(memmberValue.c_str(), memmberName); xmlNode->addChild(memberNode); } else { //behaviac::string memmberNameFull = typeNameT + "::" + memmberName; //xmlNode->setAttr(memmberNameFull.c_str(), memmberValue.c_str()); xmlNode->setAttr(memmberName.c_str(), memmberValue.c_str()); } } bIsStructMember = false; //skip ';' posBegin = posEnd + 1; //{color=0;id=;type={bLive=false;name=0;weight=0;};transit_points=3:{coordX=0;coordY=0;}|{coordX=0;coordY=0;}|{coordX=0;coordY=0;};} posEnd = src.find_first_of(';', posBegin); if (posEnd > posCloseBrackets) { break; } } return xmlNode; }