khanat-opennel-code/code/ryzom/server/src/ags_test/command_event_manager.cpp
acemtp@users.sourceforge.net d5c601ffa5 initial version
2010-05-06 02:08:41 +02:00

1120 lines
25 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 <http://www.gnu.org/licenses/>.
#include "command_event_manager.h"
#include "nel/misc/time_nl.h"
#include "nel/misc/file.h"
#include "nel/misc/path.h"
#include "nel/misc/command.h"
#include "nel/misc/variable.h"
#include "game_share/tick_event_handler.h"
using namespace std;
using namespace NLMISC;
using namespace NLNET;
//using CCommandEventManager::CScript;
//using CCommandEventManager::CScriptNode;
//using CCommandEventManager::CEnvironment;
#define EXEC_CHILD_AND_EXIT(child) if (child) return executeChild(child, env)
#define EXEC_CHILD_AND_EXIT_ON_HALT_ERROR(child) if (child) { EState state = executeChild(child, env); if (state==Halt || state==Error) return state; }
CCommandEventManager::TScriptMap CCommandEventManager::_RunningScripts;
string CCommandEventManager::_Empty("");
/*
* Constructor
*/
CCommandEventManager::CCommandEventManager()
{
}
//
// Env
//
string CCommandEventManager::CEnvironment::replace(const string &text)
{
uint start = 0, stop;
string replaced = text;
do
{
start = replaced.find_first_of('$', start);
if (start == string::npos || start == replaced.size()-1)
break;
if (replaced[start+1] == '$')
{
replaced.erase(start, 1);
++start;
continue;
}
else if (replaced[start+1] == '(')
{
stop = replaced.find_first_of(')', start+1);
if (stop == string::npos)
break;
string val = get(replaced.substr(start+2, stop-start-2));
replaced.erase(start, stop-start+1);
replaced.insert(start, val);
start += val.size();
}
else if (replaced[start+1] == '[')
{
stop = replaced.find_first_of(']', start+1);
if (stop == string::npos)
break;
string var = replaced.substr(start+2, stop-start-2);
string val = "";
ICommand::TCommand::iterator it = ICommand::Commands->find(var);
if (it != ICommand::Commands->end())
{
IVariable *variable = dynamic_cast<IVariable*>((*it).second);
if (variable != NULL)
{
val = variable->toString();
}
}
replaced.erase(start, stop-start+1);
replaced.insert(start, val);
start += val.size();
}
else
{
++start;
}
}
while (start < replaced.size());
return replaced;
}
//
// Script nodes
//
// -----------------------------------------------------------
// list node
class CInstListNode : public CCommandEventManager::CScriptNode
{
public:
vector<CCommandEventManager::CScriptNode*> Nodes;
uint NextToRun;
CInstListNode() : NextToRun(0) {}
~CInstListNode()
{
uint i;
for (i=0; i<Nodes.size(); ++i)
delete Nodes[i];
}
EState execute(CCommandEventManager::CEnvironment &env)
{
for (; NextToRun<Nodes.size(); ++NextToRun)
{
EXEC_CHILD_AND_EXIT_ON_HALT_ERROR(Nodes[NextToRun]);
}
NextToRun = 0;
return Ok;
}
};
// -----------------------------------------------------------
// if node
class CIfNode : public CCommandEventManager::CScriptNode
{
public:
string Condition;
CCommandEventManager::CScriptNode *TrueStatement,
*FalseStatement;
CIfNode() : TrueStatement(NULL), FalseStatement(NULL) {}
~CIfNode()
{
if (TrueStatement)
delete TrueStatement;
if (FalseStatement)
delete FalseStatement;
}
EState execute(CCommandEventManager::CEnvironment &env)
{
if (CurrentRun)
return goOnCurrentRun(env);
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] if %s", Root->Name.c_str(), Line, Condition.c_str());
double res;
CEvalNumExpr::TReturnState ev = env.evalExpression(Condition.c_str(), res, NULL);
if (ev == CEvalNumExpr::NoError)
{
if (res != 0.0)
{
// exec true statement
EXEC_CHILD_AND_EXIT(TrueStatement);
}
else
{
// exec false statement
EXEC_CHILD_AND_EXIT(FalseStatement);
}
}
else
{
return Error;
}
return Ok;
}
};
// -----------------------------------------------------------
// while node
class CWhileNode : public CCommandEventManager::CScriptNode
{
public:
string Condition;
CCommandEventManager::CScriptNode *Statement;
CWhileNode() : Statement(NULL) {}
~CWhileNode()
{
if (Statement)
delete Statement;
}
EState execute(CCommandEventManager::CEnvironment &env)
{
if (CurrentRun)
{
EState state = goOnCurrentRun(env);
if (state == Error || state == Halt)
return state;
}
do
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] while %s", Root->Name.c_str(), Line, Condition.c_str());
double res;
CEvalNumExpr::TReturnState ev = env.evalExpression(Condition.c_str(), res, NULL);
if (ev == CEvalNumExpr::NoError)
{
if (res != 0.0)
{
// exec true statement
if (Statement)
{
EXEC_CHILD_AND_EXIT_ON_HALT_ERROR(Statement);
}
}
else
{
break;
}
}
else
{
return Error;
}
}
while (true);
return Ok;
}
};
// -----------------------------------------------------------
// cmd node
class CCmdNode : public CCommandEventManager::CScriptNode
{
public:
string Command;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] cmd %s", Root->Name.c_str(), Line, Command.c_str());
ICommand::execute(env.replace(Command), *InfoLog);
return Ok;
}
};
// -----------------------------------------------------------
// set text node
class CSetTextNode : public CCommandEventManager::CScriptNode
{
public:
string Variable;
string Text;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] set$ %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str());
env.set(Variable, env.replace(Text));
return Ok;
}
};
// -----------------------------------------------------------
// set text node
class CSetNumericNode : public CCommandEventManager::CScriptNode
{
public:
string Variable;
string Text;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] set# %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str());
double res;
CEvalNumExpr::TReturnState ev = env.evalExpression(Text.c_str(), res, NULL);
if (ev == CEvalNumExpr::NoError)
{
env.set(Variable, toString(res));
return Ok;
}
else
{
return Error;
}
}
};
// -----------------------------------------------------------
// erase node
class CEraseNode : public CCommandEventManager::CScriptNode
{
public:
string Variable;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] erase %s", Root->Name.c_str(), Line, Variable.c_str());
env.erase(Variable);
return Ok;
}
};
// -----------------------------------------------------------
// wait node
class CWaitNode : public CCommandEventManager::CScriptNode
{
public:
uint Wait;
TGameCycle StartCycle;
CWaitNode() : Wait(0), StartCycle(0) {}
EState execute(CCommandEventManager::CEnvironment &env)
{
if (!StartCycle)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] wait %d", Root->Name.c_str(), Line, Wait);
StartCycle = CTickEventHandler::getGameCycle();
return Halt;
}
else if (CTickEventHandler::getGameCycle() >= StartCycle+Wait)
{
StartCycle = 0;
return Ok;
}
else
{
return Halt;
}
}
};
// -----------------------------------------------------------
// display node
class CDisplayNode : public CCommandEventManager::CScriptNode
{
public:
string Text;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] ? %s", Root->Name.c_str(), Line, Text.c_str());
nlinfo("[%s] %s", Root->Name.c_str(), env.replace(Text).c_str());
return Ok;
}
};
// -----------------------------------------------------------
// wait node
class CReceiveNode : public CCommandEventManager::CScriptNode
{
public:
bool Waiting;
string Expression;
CReceiveNode() : Waiting(false) {}
EState execute(CCommandEventManager::CEnvironment &env)
{
if (!Waiting)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] receive %s", Root->Name.c_str(), Line, Expression.c_str());
Waiting = true;
}
double res;
CEvalNumExpr::TReturnState ev = env.evalExpression(Expression.c_str(), res, NULL);
if (ev != CEvalNumExpr::NoError)
return Error;
else
{
if (res != 0.0)
{
Waiting = false;
return Ok;
}
else
{
return Halt;
}
}
return (ev != CEvalNumExpr::NoError) ? Error : ((res != 0.0) ? Ok : Halt);
}
};
// -----------------------------------------------------------
// wait node
class CSendNode : public CCommandEventManager::CScriptNode
{
public:
string Variable;
string Text;
EState execute(CCommandEventManager::CEnvironment &env)
{
if (Root->Verbose)
nldebug("[%s:%d:DEBUG] send %s %s", Root->Name.c_str(), Line, Variable.c_str(), Text.c_str());
CCommandEventManager::sendEvent(Variable, env.replace(Text));
return Ok;
}
};
// -----------------------------------------------------------
// Parse script
CCommandEventManager::CScript *parsedScript = NULL;
enum
{
TOKEN_UNKNOWN = 0,
TOKEN_END,
TOKEN_COMMENT,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_ENDIF,
TOKEN_WHILE,
TOKEN_ENDLOOP,
TOKEN_CMD, // execute a command (while command is evaluated using $(...) syntax)
TOKEN_SETTEXT, // set a variable to a text value (evaluated using $(...) syntax)
TOKEN_SETNUMERIC, // set a variable to a numeric value (evaluated as a normal numeric expression, variables don't need any $(...) form)
TOKEN_ERASE, // erase a variable from env
TOKEN_WAIT, // wait for n game cycles
TOKEN_RECEIVE, // wait for expression to be evaluated to true
TOKEN_SEND,
TOKEN_DISPLAY,
};
class CAssociatedToken
{
public:
CAssociatedToken(uint token, string chars) : Token(token), Chars(chars) {}
uint Token;
string Chars;
};
CAssociatedToken CTable[] =
{
CAssociatedToken(TOKEN_IF, "if"),
CAssociatedToken(TOKEN_ELSE, "else"),
CAssociatedToken(TOKEN_ENDIF, "endif"),
CAssociatedToken(TOKEN_WHILE, "while"),
CAssociatedToken(TOKEN_ENDLOOP, "endloop"),
CAssociatedToken(TOKEN_CMD, "cmd"),
CAssociatedToken(TOKEN_SETTEXT, "setText"),
CAssociatedToken(TOKEN_SETTEXT, "set$"),
CAssociatedToken(TOKEN_SETNUMERIC, "setNumeric"),
CAssociatedToken(TOKEN_SETNUMERIC, "set#"),
CAssociatedToken(TOKEN_ERASE, "erase"),
CAssociatedToken(TOKEN_WAIT, "wait"),
CAssociatedToken(TOKEN_RECEIVE, "receive"),
CAssociatedToken(TOKEN_SEND, "send"),
CAssociatedToken(TOKEN_DISPLAY, "display"),
CAssociatedToken(TOKEN_DISPLAY, "?"),
CAssociatedToken(TOKEN_COMMENT, "!"),
};
class CParser
{
public:
const char *Text;
const char *TokenStart;
uint Line;
CParser() : Text(NULL), Line(0) {}
void skipSpace()
{
while (*Text != '\0' && (*Text == ' ' || *Text == '\t'))
++Text;
}
void skipAllSpace()
{
while (*Text != '\0' && (*Text == ' ' || *Text == '\t' || *Text == '\r' || *Text == '\n'))
{
if (*Text == '\n')
++Line;
++Text;
}
}
void skipToSpace()
{
while (*Text != '\0' && (*Text != ' ' && *Text != '\t' && *Text != '\r' && *Text != '\n'))
++Text;
}
void skipLine()
{
while (*Text != '\0' && (*Text != '\n' && *Text != '\r'))
++Text;
}
string getLine()
{
const char *first = Text;
const char *last = Text;
while (*Text != '\0' && (*Text != '\n' && *Text != '\r'))
{
if (*Text != ' ' && *Text != '\t')
last = Text;
++Text;
}
return string(first, last-first+1);
}
bool compare(const char *a, const char *t)
{
while (*t>32 && *t==*a)
++t, ++a;
return ((*a=='\0' || *a==' ' || *a=='\n' || *a=='\r' || *a=='\t')
&& (*t=='\0' || *t==' ' || *t=='\n' || *t=='\r' || *t=='\t'));
}
string getWord()
{
skipSpace();
const char *start = Text;
skipToSpace();
return string(start, Text-start);
}
uint getToken()
{
skipAllSpace();
if (*Text == '\0')
return TOKEN_END;
TokenStart = Text;
skipToSpace();
skipSpace();
uint i;
for (i=0; i<sizeof(CTable)/sizeof(CAssociatedToken); ++i)
if (compare(CTable[i].Chars.c_str(), TokenStart))
return CTable[i].Token;
return TOKEN_UNKNOWN;
}
void rewindToken()
{
Text = TokenStart;
}
};
CParser Parser;
CCommandEventManager::CScriptNode *parseInstructionList();
//
CCommandEventManager::CScriptNode *parseIf()
{
Parser.skipSpace();
CIfNode *node = new CIfNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Condition = Parser.getLine();
Parser.skipLine();
node->TrueStatement = parseInstructionList();
uint token = Parser.getToken();
if (token == TOKEN_ELSE)
{
node->FalseStatement = parseInstructionList();
token = Parser.getToken();
}
if (token != TOKEN_ENDIF)
{
nlwarning("[%s] Unknown token found in structure if, expected endif at line %d. Skip line", parsedScript->Name.c_str(), Parser.Line);
Parser.skipLine();
}
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseWhile()
{
Parser.skipSpace();
CWhileNode *node = new CWhileNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Condition = Parser.getLine();
Parser.skipLine();
node->Statement = parseInstructionList();
if (Parser.getToken() != TOKEN_ENDLOOP)
{
nlwarning("[%s] Unknown token found in structure while, expected endloop at line %d. Skip line", parsedScript->Name.c_str(), Parser.Line);
Parser.skipLine();
}
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseCmd()
{
Parser.skipSpace();
CCmdNode *node = new CCmdNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Command = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseSetText()
{
Parser.skipSpace();
CSetTextNode *node = new CSetTextNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Variable = Parser.getWord();
Parser.skipSpace();
node->Text = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseSetNumeric()
{
Parser.skipSpace();
CSetNumericNode *node = new CSetNumericNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Variable = Parser.getWord();
Parser.skipSpace();
node->Text = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseErase()
{
Parser.skipSpace();
CEraseNode *node = new CEraseNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Variable = Parser.getWord();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseWait()
{
Parser.skipSpace();
CWaitNode *node = new CWaitNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Wait = atoi(Parser.getWord().c_str());
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseReceive()
{
Parser.skipSpace();
CReceiveNode *node = new CReceiveNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Expression = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseSend()
{
Parser.skipSpace();
CSendNode *node = new CSendNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Variable = Parser.getWord();
Parser.skipSpace();
node->Text = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseDisplay()
{
Parser.skipSpace();
CDisplayNode *node = new CDisplayNode();
node->Root = parsedScript;
node->Line = Parser.Line;
node->Text = Parser.getLine();
Parser.skipLine();
return (CCommandEventManager::CScriptNode*)node;
}
//
CCommandEventManager::CScriptNode *parseInstructionList()
{
CInstListNode *list = new CInstListNode();
list->Root = parsedScript;
list->Line = Parser.Line;
do
{
uint token = Parser.getToken();
switch (token)
{
case TOKEN_END:
return list;
break;
case TOKEN_IF:
list->Nodes.push_back(parseIf());
break;
case TOKEN_ELSE:
Parser.rewindToken();
return list;
break;
case TOKEN_ENDIF:
Parser.rewindToken();
return list;
break;
case TOKEN_WHILE:
list->Nodes.push_back(parseWhile());
break;
case TOKEN_ENDLOOP:
Parser.rewindToken();
return list;
break;
case TOKEN_CMD:
list->Nodes.push_back(parseCmd());
break;
case TOKEN_SETTEXT:
list->Nodes.push_back(parseSetText());
break;
case TOKEN_SETNUMERIC:
list->Nodes.push_back(parseSetNumeric());
break;
case TOKEN_ERASE:
list->Nodes.push_back(parseErase());
break;
case TOKEN_WAIT:
list->Nodes.push_back(parseWait());
break;
case TOKEN_RECEIVE:
list->Nodes.push_back(parseReceive());
break;
case TOKEN_SEND:
list->Nodes.push_back(parseSend());
break;
case TOKEN_DISPLAY:
list->Nodes.push_back(parseDisplay());
break;
case TOKEN_COMMENT:
Parser.skipLine();
break;
case TOKEN_UNKNOWN:
nlwarning("[%s] Unknow token at line %d: '%20s...', line ignored", parsedScript->Name.c_str(), Parser.Line, Parser.TokenStart);
Parser.skipLine();
break;
}
}
while (true);
return (CCommandEventManager::CScriptNode*)list;
}
bool CCommandEventManager::CScript::parse(const char *text)
{
parsedScript = this;
Parser.Text = text;
Parser.Line = 1;
Root = parseInstructionList();
return true;
}
// -----------------------------------------------------------
// Runs script till it is finished or it waits for an event
bool CCommandEventManager::CScript::run()
{
CScriptNode::EState state = Root->execute(Environment);
if (state == CScriptNode::Error)
{
nlwarning("[%s] An error occured in script, script ended", Name.c_str());
return false;
}
else if (state == CScriptNode::Ok)
{
nlinfo("[%s] Script succesfully terminated, script ended", Name.c_str());
return false;
}
else
{
return true;
}
}
//
void cbProcessScriptEvent( CMessage& msgin, const string &serviceName, uint16 serviceId )
{
string var;
string value;
msgin.serial(var, value);
CCommandEventManager::processEvent(var, value);
}
TUnifiedCallbackItem CbScriptArray[] =
{
{ "S_EVENT", cbProcessScriptEvent, }
};
//
void CCommandEventManager::init()
{
CUnifiedNetwork::getInstance()->addCallbackArray( CbScriptArray, sizeof(CbScriptArray)/sizeof(CbScriptArray[0]) );
}
//
void CCommandEventManager::release()
{
TScriptMap::iterator it;
for (it = _RunningScripts.begin(); it != _RunningScripts.end(); ++it)
delete (*it).second;
_RunningScripts.clear();
}
//
bool CCommandEventManager::update()
{
TScriptMap::iterator it;
for (it = _RunningScripts.begin(); it != _RunningScripts.end(); )
if (!((*it).second->run()))
{
TScriptMap::iterator itn = it++;
delete (*itn).second;
_RunningScripts.erase(itn);
}
else
{
++it;
}
return true;
}
//
bool CCommandEventManager::runScript(const std::string &scriptName, const std::string &scriptFile, bool verbosity)
{
if (_RunningScripts.find(scriptName) != _RunningScripts.end())
{
nlwarning("Script '%s' already running, stop script or wait for its end before restarting it", scriptName.c_str());
return false;
}
string fname = CPath::lookup(scriptFile, false);
if (fname == "")
{
nlwarning("Can't find file '%s' to launch script '%s'", scriptFile.c_str(), scriptName.c_str());
return false;
}
CIFile file(fname);
uint sz = file.getFileSize();
char *buffer = new char[sz+1];
try
{
file.serialBuffer((uint8*)buffer, sz);
buffer[sz] = '\0';
}
catch (EReadError&)
{
nlwarning("Unable to read script file '%s' for script '%s'", scriptFile.c_str(), scriptName.c_str());
delete buffer;
return false;
}
CScript *script = new CScript(scriptName);
script->Verbose = verbosity;
if (!script->parse(buffer))
{
nlwarning("Unable to parse script file '%s' for script '%s'", scriptFile.c_str(), scriptName.c_str());
delete buffer;
delete script;
return false;
}
script->init();
nlinfo("Loaded script file '%s' for script '%s' and initialized, ready to run (verbosity %s)", scriptFile.c_str(), scriptName.c_str(), verbosity ? "on":"off");
_RunningScripts.insert(make_pair<string,CScript*>(scriptName, script));
delete buffer;
return true;
}
bool CCommandEventManager::stopScript(const std::string &scriptName)
{
TScriptMap::iterator it = _RunningScripts.find(scriptName);
if (it == _RunningScripts.end())
{
nlwarning("Can't stop script '%s', script not found (already stopped?)", scriptName.c_str());
return false;
}
// delete script
delete (*it).second;
_RunningScripts.erase(it);
return true;
}
const std::string &CCommandEventManager::getVarInScript(const std::string &scriptName, const std::string &varName)
{
TScriptMap::iterator it = _RunningScripts.find(scriptName);
if (it == _RunningScripts.end())
{
nlwarning("Can't find script '%s' to get variable '%s'", scriptName.c_str(), varName.c_str());
return _Empty;
}
return (*it).second->Environment.get(varName);
}
void CCommandEventManager::setVarInScript(const std::string &scriptName, const std::string &varName, const std::string &value)
{
TScriptMap::iterator it = _RunningScripts.find(scriptName);
if (it == _RunningScripts.end())
{
nlwarning("Can't find script '%s' to set variable '%s' to '%s'", scriptName.c_str(), varName.c_str(), value.c_str());
return;
}
(*it).second->Environment.set(varName, value);
}
void CCommandEventManager::eraseVarInScript(const std::string &scriptName, const std::string &varName)
{
TScriptMap::iterator it = _RunningScripts.find(scriptName);
if (it == _RunningScripts.end())
{
nlwarning("Can't find script '%s' to erase variable '%s'", scriptName.c_str(), varName.c_str());
return;
}
(*it).second->Environment.erase(varName);
}
void CCommandEventManager::sendEvent(const std::string &var, const std::string &value)
{
CMessage msg("S_EVNT");
msg.serial(const_cast<string&>(var));
msg.serial(const_cast<string&>(value));
//CUnifiedNetwork::getInstance()->sendAll(msg);
processEvent(var, value);
}
void CCommandEventManager::processEvent(const std::string &var, const std::string &value)
{
TScriptMap::iterator it;
for (it = _RunningScripts.begin(); it != _RunningScripts.end(); ++it)
(*it).second->Environment.set(var, value);
}
//
void CCommandEventManager::setScriptVerbose(const std::string &scriptName, bool verbosity)
{
TScriptMap::iterator it = _RunningScripts.find(scriptName);
if (it == _RunningScripts.end())
{
nlwarning("Can't find script '%s' to set verbosity", scriptName.c_str());
return;
}
(*it).second->Verbose = verbosity;
}
// commands
NLMISC_COMMAND(runScript, "Run a script","<scriptName> <fileName> [verbosity]")
{
if (args.size() < 2 || args.size() > 3)
return false;
bool verb = false;
if (args.size() == 3)
verb = !(args[2] == "0");
CCommandEventManager::runScript(args[0], args[1], verb);
return true;
}
NLMISC_COMMAND(stopScript, "Stop a running script","<scriptName>")
{
if (args.size() != 1)
return false;
CCommandEventManager::stopScript(args[0]);
return true;
}
NLMISC_COMMAND(getVarInScript, "Get a variable value in a script","<scriptName> <varName>")
{
if (args.size() != 2)
return false;
CCommandEventManager::getVarInScript(args[0], args[1]);
return true;
}
NLMISC_COMMAND(setVarInScript, "Set a variable value in a script","<scriptName> <varName> <value>")
{
if (args.size() != 3)
return false;
CCommandEventManager::setVarInScript(args[0], args[1], args[2]);
return true;
}
NLMISC_COMMAND(eraseVarInScript, "Erase a variable value in a script","<scriptName> <varName>")
{
if (args.size() != 2)
return false;
CCommandEventManager::eraseVarInScript(args[0], args[1]);
return true;
}
NLMISC_COMMAND(sendEvent, "Send a script event to all scripts (on all services of the shard)","<varName> <value>")
{
if (args.size() != 2)
return false;
CCommandEventManager::sendEvent(args[0], args[1]);
return true;
}