// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . //---------------------------------------------------------------------------- #include "nel/misc/command.h" #include "nel/misc/debug.h" #include "nel/misc/config_file.h" #include "nel/misc/path.h" #include "nel/net/service.h" #include "aids_actions.h" using namespace NLMISC; using namespace NLNET; using namespace std; //---------------------------------------------------------------------------- // Stuff for debug message logging //---------------------------------------------------------------------------- static bool verboseLog=false; #define TAB toString("%*s",CurrentMgrDfnNodes.size()*4,"").c_str() #define TAB1 toString("%*s",CurrentMgrDfnNodes.size()*4-4,"").c_str() #define LOG if (!verboseLog) {} else nlinfo NLMISC_COMMAND(verboseAIDSActionLog,"Turn on or off or check the state of verbose AIDSAction parser logging","") { if(args.size()>1) return false; if(args.size()==1) StrToBool (verboseLog, args[0]); nlinfo("verboseAIDSActionLogging is %s",verboseLog?"ON":"OFF"); return true; } //---------------------------------------------------------------------------- // Singleton data instantiation //---------------------------------------------------------------------------- CAIDSActions *CAIDSActions::Instance=NULL; uint CAIDSActions::CurrentManager=0; //---------------------------------------------------------------------------- // Local utility functions and variables //---------------------------------------------------------------------------- static uint BadParseDepth=0; static CAIManager::SMgrDfnNode DefaultNode; static std::vector CurrentMgrDfnNodes; static bool FoundAIData=false; static std::string FileName; static void Prepare(CAIManager::SMgrDfnNode &node) { // recurse through children for (uint i=0;iConfigFile.getVarPtr(std::string("IgnorePrimitives")); std::vector ignoreFiles; for (uint i=0;isize();++i) ignoreFiles.push_back(CFile::getFilenameWithoutExtension(varPtr->asString(i))); //append this file to the vector and pass it back to the config file manager for storage ignoreFiles.push_back(NLMISC::CFile::getFilenameWithoutExtension(fileName)); varPtr->setAsString(ignoreFiles); IService::getInstance()->ConfigFile.save(); } } void CAIDSActions::begin(const std::string &contextName) { LOG("%s{ // %s",TAB,contextName.c_str()); uint i; // if we've encountered a parse problem just count levels of indentation if (BadParseDepth) { ++BadParseDepth; return; } // if the CurrentMgrDfnNodes vector is empty then we must be parsing a new manager if (CurrentMgrDfnNodes.empty()) { nlinfo("- Parsing: %s",contextName.c_str()); // update variables used in this source file (AIDS_ACTIONS.CPP) FoundAIData=true; CurrentMgrDfnNodes.push_back(&(CAIManager::getManagerById(CurrentManager)->MgrDfnRootNode)); CurrentMgrDfnNodes[0]->Name=contextName; // reset the 'visited' flags for the manager's data tree Prepare(*CurrentMgrDfnNodes[0]); CurrentMgrDfnNodes[0]->Visited=true; // copy the default dfn nodes to the current node and add a 'set_slot' action CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; for (uint i=0;iData.push_back(DefaultNode.Data[i]); // add a set_slot action with value uint slot id = CurrentManager std::vector args; args.push_back(CAIActions::CArg(CurrentManager)); curNode->Data.push_back(CAIManager::SMgrDfnElm(*(uint64*)"SET_SLOT",args)); } else { CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; // try to find a node with the name matching contextName // if there are a number of nodes with the same name then this code should work ok as // it uses the 'visited' flags to avoid multi-use of same node slot CAIManager::SMgrDfnNode *node=NULL; for (i=0;iChild.size();++i) if ((curNode->Child[i]->Name.empty() || curNode->Child[i]->Name==contextName) && !curNode->Child[i]->Visited) { node=(curNode->Child[i]); break; } // if need be allocate a new data node if (i==curNode->Child.size()) { curNode->Child.push_back(new CAIManager::SMgrDfnNode(contextName)); node=curNode->Child[i]; } // add a set_slot action with value uint slot id = i std::vector args; args.push_back(CAIActions::CArg(i)); curNode->Child[i]->Data.push_back(CAIManager::SMgrDfnElm(*(uint64*)"SET_SLOT",args)); // update variables used in this source file (AIDS_ACTIONS.CPP) CurrentMgrDfnNodes.push_back(node); node->Visited=true; } } void CAIDSActions::end(const std::string &contextName) { LOG("%s} // %s",TAB1,contextName.c_str()); // if we've encountered a parse problem just count levels of indentation if (BadParseDepth) { --BadParseDepth; return; } // make sure the name of the context that we're closing matches the name of the context that we opened CAIManager::SMgrDfnNode *curNode=CurrentMgrDfnNodes[CurrentMgrDfnNodes.size()-1]; nlassert(contextName==curNode->Name); // close this context CurrentMgrDfnNodes.pop_back(); // if we've finished then do some housekeeping if (CurrentMgrDfnNodes.empty()) { // run back through tree stripping out unvisitted entries Clean(*curNode); } } void CAIDSActions::execute(uint64 action,const std::vector &args) { // if we've encountered a parse problem don't execute... if (BadParseDepth) { return; } // generate a string to describe the action std::string txt; txt+=toString("%-8.8s",&action); txt+='('; for (uint i=0;iData.push_back(CAIManager::SMgrDfnElm(action,args)); }