示例#1
0
bool Terminal::execFile(QString filePath) {
    if(!Utils::isExtension(filePath, QString("js"))) {
        std::cout << "File Invalid..."
                  << std::endl
                  << "Acceptable extension *.js";
        return false;
    }

    QString script = Utils::getContent(filePath);

    if(script.isEmpty()) { return false; }

    QScriptSyntaxCheckResult result = this->m_engine->checkSyntax(script);

    if(result.state() == QScriptSyntaxCheckResult::Error) {
        QString error("Error on line %1 column %2\nMessage: %3");
        error = error.arg(QString::number(result.errorLineNumber()),
                          QString::number(result.errorColumnNumber()),
                          result.errorMessage());

        std::cout << error.toAscii().constData() << std::endl;
        return false;
    }

    Jsws *jsws = new Jsws(this->m_engine, script,parent());
    QScriptValue value = this->m_engine->newQObject(jsws);
    this->m_engine->globalObject().setProperty("WS", value);
    this->m_engine->evaluate(script);
    return true;
}
示例#2
0
QScriptValue ScriptTask::runScript(QScriptEngine* engine, const QMap<QString, QScriptValue>& inputParametersMap, const QString& scriptText, TaskStateInfo& stateInfo) {
    // create new script engine
    QScriptValue result;

    // setup all input params as global vars
    QScriptValue thiz = engine->globalObject();
    foreach(const QString& varName, inputParametersMap.keys()) {
        QScriptValue varVal = inputParametersMap.value(varName);
        thiz.setProperty(varName, varVal);
    }

    // check script syntax
    QScriptSyntaxCheckResult syntaxResult = engine->checkSyntax(scriptText);
    if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid) {
        stateInfo.setError(tr("Script syntax check failed! Line: %1, error: %2").arg(syntaxResult.errorLineNumber()).arg(syntaxResult.errorMessage()));
        return result;
    }

    // run the script
    result = engine->evaluate(scriptText);

    if (engine->hasUncaughtException()) {
        stateInfo.setError(tr("Exception during script execution! Line: %1, error: %2")
                        .arg(engine->uncaughtExceptionLineNumber()).arg(engine->uncaughtExceptionBacktrace().join("\n")));
    }
    return result;
}
示例#3
0
bool FuncCallScriptAction::check(const QString &xmlFile, const TypeRule *rule,
                                 SymFactory *factory)
{
    Q_UNUSED(rule);
    Q_UNUSED(factory);

    // Delete old program
    if (_program) {
        delete _program;
        _program = 0;
    }

    // Read the contents of the script file
    QFile scriptFile(_scriptFile);
    if (!scriptFile.open(QFile::ReadOnly))
        ioError(QString("Error opening file \"%1\" for reading.")
                    .arg(_scriptFile));
    _program = new QScriptProgram(scriptFile.readAll(), _scriptFile);

    // Basic syntax check
    QScriptSyntaxCheckResult result =
            QScriptEngine::checkSyntax(_program->sourceCode());
    if (result.state() != QScriptSyntaxCheckResult::Valid) {
        typeRuleError2(xmlFile, srcLine(), -1,
                       QString("Syntax error in file %1 line %2 column %3: %4")
                               .arg(ShellUtil::shortFileName(_scriptFile))
                               .arg(result.errorLineNumber())
                               .arg(result.errorColumnNumber())
                               .arg(result.errorMessage()));
    }
    // Check if the function exists
    ScriptEngine eng(0);
    ScriptEngine::FuncExistsResult ret =
            eng.functionExists(_function, *_program);
    if (ret == ScriptEngine::feRuntimeError) {
        QString err;
        if (eng.hasUncaughtException()) {
            err = QString("Uncaught exception at line %0: %1")
                    .arg(eng.uncaughtExceptionLineNumber())
                    .arg(eng.lastError());
            QStringList bt = eng.uncaughtExceptionBacktrace();
            for (int i = 0; i < bt.size(); ++i)
                err += "\n    " + bt[i];
        }
        else
            err = eng.lastError();
        typeRuleError2(xmlFile, srcLine(), -1,
                       QString("Runtime error in file %1: %2")
                               .arg(ShellUtil::shortFileName(_scriptFile))
                               .arg(err));
    }
    else if (ret == ScriptEngine::feDoesNotExist) {
        typeRuleError2(xmlFile, srcLine(), -1,
                       QString("Function \"%1\" is not defined in file \"%2\".")
                               .arg(_function)
                               .arg(ShellUtil::shortFileName(_scriptFile)));
    }

    return true;
}
示例#4
0
bool ProgramScriptAction::check(const QString &xmlFile, const TypeRule *rule,
                                SymFactory *factory)
{
    Q_UNUSED(rule);
    Q_UNUSED(factory);

    // Delete old program
    if (_program) {
        delete _program;
        _program = 0;
    }

    QScriptSyntaxCheckResult result =
            QScriptEngine::checkSyntax(_srcCode);
    if (result.state() != QScriptSyntaxCheckResult::Valid) {
        typeRuleError2(xmlFile,
                       srcLine() + result.errorLineNumber() - 1,
                       result.errorColumnNumber(),
                       QString("Syntax error: %1")
                            .arg(result.errorMessage()));
    }
    else {
        // Wrap the code into a function so that the return statement
        // is available to the code
        QString code = QString("function %1() {\n%2\n}")
                .arg(js::inlinefunc).arg(_srcCode);
        _program = new QScriptProgram(code, xmlFile, srcLine() - 1);
    }

    return true;
}
示例#5
0
//-- \subsection{include(file)}
//-- Includes another source code file at this point. This is experimental, and breaks the
//-- lint tool, so use with care.
static QScriptValue js_include(QScriptContext *context, QScriptEngine *engine)
{
	QString path = context->argument(0).toString();
	UDWORD size;
	char *bytes = NULL;
	if (!loadFile(path.toAscii().constData(), &bytes, &size))
	{
		debug(LOG_ERROR, "Failed to read include file \"%s\"", path.toAscii().constData());
		return QScriptValue(false);
	}
	QString source = QString::fromAscii(bytes, size);
	free(bytes);
	QScriptSyntaxCheckResult syntax = QScriptEngine::checkSyntax(source);
	if (syntax.state() != QScriptSyntaxCheckResult::Valid)
	{
		debug(LOG_ERROR, "Syntax error in include %s line %d: %s", 
		      path.toAscii().constData(), syntax.errorLineNumber(), syntax.errorMessage().toAscii().constData());
		return QScriptValue(false);
	}
	context->setActivationObject(engine->globalObject());
	context->setThisObject(engine->globalObject());
	QScriptValue result = engine->evaluate(source, path);
	if (engine->hasUncaughtException())
	{
		int line = engine->uncaughtExceptionLineNumber();
		debug(LOG_ERROR, "Uncaught exception at line %d, include file %s: %s",
		      line, path.toAscii().constData(), result.toString().toAscii().constData());
		return QScriptValue(false);
	}
	return QScriptValue(true);
}
示例#6
0
QVariant CBDS::getSettingsFromScript(const QString &filename)
{
    QFile f(filename);
    if (f.open(QIODevice::ReadOnly))
    {
        QString appcode(f.readAll());
        f.close();
        QScriptSyntaxCheckResult res = m_engine.checkSyntax(appcode);
        if (res.state() != QScriptSyntaxCheckResult::Valid)
        {
            emit error(QString("SyntaxCheck Failed: Line: %1 Column: %2: %3").arg(res.errorLineNumber()).arg(res.errorColumnNumber()).arg(res.errorMessage()));
            return QVariant();
        }

        QScriptContext *ctx = m_engine.pushContext();
        CBJSObject js;
        CBObjectBase cbo(&m_engine, m_roomowner);
        ctx->activationObject().setProperty("cb", m_engine.newQObject(&cbo));
        ctx->activationObject().setProperty("cbjs", m_engine.newQObject(&js));
        QScriptValue ret = m_engine.evaluate(appcode, QFileInfo(filename).fileName());
        if (ret.isError())
        {
            emit error(ret.toString());
            m_engine.popContext();
            return QVariant();
        }

        m_engine.popContext();
        return cbo.getSettingsChoices().toVariant();
    }
    emit error("Can't open file: " + filename);
    return QVariant();
}
示例#7
0
void ScriptingAsset::load()
{
    if( !isLoaded() )
    {
        QFile script( file().toLocalFile() );
        if( script.open( QIODevice::ReadOnly ) )
        {
            d->script = script.readAll();
            mimeData()->setText( d->script );
        }
        // Don't attempt to do anything if the script is empty
        if( d->script.isEmpty() )
            return;

        QScriptSyntaxCheckResult result = ScriptingEngine::instance()->registerAsset( this );
        if( result.state() != QScriptSyntaxCheckResult::Valid )
        {
            debug( tr( "Script error %1 (%2,%3): %4" ).arg( fullyQualifiedName() ).arg( result.errorLineNumber() ).arg( result.errorColumnNumber() ).arg( result.errorMessage() ) );
        }
        else
        {
            Asset::load();
        }
    }
}
void JavascriptInstance::Load()
{
    PROFILE(JSInstance_Load);
    if (!engine_)
        CreateEngine();

    if (sourceFile.isEmpty() && scriptRefs_.empty())
    {
        LogError("JavascriptInstance::Load: No script content to load!");
        return;
    }
    // Can't specify both a file source and an Asset API source.
    if (!sourceFile.isEmpty() && !scriptRefs_.empty())
    {
        LogError("JavascriptInstance::Load: Cannot specify both an local input source file and a list of script refs to load!");
        return;
    }

    bool useAssetAPI = !scriptRefs_.empty();
    size_t numScripts = useAssetAPI ? scriptRefs_.size() : 1;

    // Determine based on code origin whether it can be trusted with system access or not
    if (useAssetAPI)
    {
        trusted_ = true;
        for(unsigned i = 0; i < scriptRefs_.size(); ++i)
            trusted_ = trusted_ && scriptRefs_[i]->IsTrusted();
    }
    else // Local file: always trusted.
    {
        program_ = LoadScript(sourceFile);
        trusted_ = true; // This is a file on the local filesystem. We are making an assumption nobody can inject untrusted code here.
        // Actually, we are assuming the attacker does not know the absolute location of the asset cache locally here, since if he makes
        // the client to load a script into local cache, he could use this code path to automatically load that unsafe script from cache, and make it trusted. -jj.
    }

    // Check the validity of the syntax in the input.
    for (size_t i = 0; i < numScripts; ++i)
    {
        QString scriptSourceFilename = (useAssetAPI ? scriptRefs_[i]->Name() : sourceFile);
        QString &scriptContent = (useAssetAPI ? scriptRefs_[i]->scriptContent : program_);

        QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(scriptContent);
        if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
        {
            LogError("Syntax error in script " + scriptSourceFilename + "," + QString::number(syntaxResult.errorLineNumber()) +
                ": " + syntaxResult.errorMessage());

            // Delete our loaded script content (if any exists).
            program_ == "";
        }
    }
}
示例#9
0
bool loadPlayerScript(QString path, int player, int difficulty)
{
	ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "Player index %d out of bounds", player);
	QScriptEngine *engine = new QScriptEngine();
	UDWORD size;
	char *bytes = NULL;
	if (!loadFile(path.toAscii().constData(), &bytes, &size))
	{
		debug(LOG_ERROR, "Failed to read script file \"%s\"", path.toAscii().constData());
		return false;
	}
	QString source = QString::fromAscii(bytes, size);
	free(bytes);
	QScriptSyntaxCheckResult syntax = QScriptEngine::checkSyntax(source);
	ASSERT_OR_RETURN(false, syntax.state() == QScriptSyntaxCheckResult::Valid, "Syntax error in %s line %d: %s", 
	                 path.toAscii().constData(), syntax.errorLineNumber(), syntax.errorMessage().toAscii().constData());
	// Remember internal, reserved names
	QScriptValueIterator it(engine->globalObject());
	while (it.hasNext())
	{
		it.next();
		internalNamespace.insert(it.name(), 1);
	}
	QScriptValue result = engine->evaluate(source, path);
	ASSERT_OR_RETURN(false, !engine->hasUncaughtException(), "Uncaught exception at line %d, file %s: %s", 
	                 engine->uncaughtExceptionLineNumber(), path.toAscii().constData(), result.toString().toAscii().constData());
	// Special functions
	engine->globalObject().setProperty("setTimer", engine->newFunction(js_setTimer));
	engine->globalObject().setProperty("queue", engine->newFunction(js_queue));
	engine->globalObject().setProperty("removeTimer", engine->newFunction(js_removeTimer));
	engine->globalObject().setProperty("include", engine->newFunction(js_include));
	engine->globalObject().setProperty("bind", engine->newFunction(js_bind));

	// Special global variables
	engine->globalObject().setProperty("me", player, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("selectedPlayer", selectedPlayer, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("gameTime", gameTime, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("difficulty", difficulty, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("mapName", game.map, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("baseType", game.base, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("alliancesType", game.alliance, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("powerType", game.power, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("maxPlayers", game.maxPlayers, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("scavengers", game.scavengers, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Regular functions
	registerFunctions(engine);

	// Register script
	scripts.push_back(engine);

	return true;
}
示例#10
0
bool ScriptLoader::performSyntaxCheck(const QString & script)
{
    QScriptSyntaxCheckResult syntaxCheck = p_engine->checkSyntax(script);

    if(syntaxCheck.state() != QScriptSyntaxCheckResult::Valid)
    {
        qDebug() << "ScriptLoader::load: Syntax error in the script";
        qDebug() << "Line" << syntaxCheck.errorLineNumber() << ": error:" << syntaxCheck.errorMessage();
        return false;
    }

    return true;
}
示例#11
0
ScriptSandbox::ScriptSandbox(const PluginManager *parent, const QString &file, const QString &script, AdamantPlugin *owner)
    : QObject()
    , _manager(parent)
    , _script(script)
    , _owner(owner)
    , _engine()
    , _engineDebugger()
    , _errorString()
{
    _engineDebugger.attachTo(&_engine);
    _program = QScriptProgram(_script, file);

    // Register MetaTypes, sometimes Q_DECL doesn't seem to cut it...
    qRegisterMetaType<Session::Request*>("Session::Request");
    qRegisterMetaType<AdamantUI*>("AdamantUI");
    qRegisterMetaType<ItemManager*>("ItemManager");
    qRegisterMetaType<AdamantUI::ApplicationTheme>("ApplicationTheme");
//    qScriptRegisterMetaType<AdamantUI::ApplicationTheme>(&_engine, [](QScriptEngine *engine, const AdamantUI::ApplicationTheme &t) -> QScriptValue {
//        return QScriptValue(static_cast<int>(t));
//    }, [](const QScriptValue &obj, AdamantUI::ApplicationTheme &t) {
//        t = static_cast<AdamantUI::ApplicationTheme>(obj.toInt32());
//    });


    QScriptSyntaxCheckResult syntax = _engine.checkSyntax(_script);
    if (syntax.state() != QScriptSyntaxCheckResult::Valid){
        _errorString = syntax.errorMessage();
    }
    else {
        // Default Globals
        addGlobalObject("manager", (QObject*)_manager);
        addGlobalObject("script", this);
        addGlobalObject("core", _manager->core());
        addGlobalObject("app", qApp);
    }

    {
        QScriptValue func = _engine.newFunction(ScriptSandbox::runFunc, this);
        _engine.globalObject().setProperty("run", func);
    }

    {
        QScriptValue func = _engine.newFunction(ScriptSandbox::importFunc, this);
        _engine.globalObject().setProperty("using", func);
    }

    {
        QScriptValue func = _engine.newFunction(ScriptSandbox::printFunc, this);
        _engine.globalObject().setProperty("print", func);
    }
}
示例#12
0
Script::Script(QString script)
{
    setObjectName(metaObject()->className());
    
    addOutputPort("ERROR");

    //From http://www.qtcentre.org/threads/10425-QtScript-newFunction-won-t-work
        
    QScriptValue that = scriptEngine.newQObject(this, QScriptEngine::QtOwnership, QScriptEngine::ExcludeChildObjects
		| QScriptEngine::ExcludeSuperClassMethods | QScriptEngine::ExcludeSuperClassProperties);
    scriptEngine.globalObject().setProperty("self",that);
    //Log in console
    scriptEngine.evaluate("function echo(str){self.scriptEcho(str);};");
    //Add input 
    scriptEngine.evaluate("function addInputPort(str){self.scriptAddInputPort(str);};");
    //Add output
    scriptEngine.evaluate("function addOutputPort(str){self.scriptAddOutputPort(str);};");
    //Set self starting
    scriptEngine.evaluate("function setSelfStarting(str){self.scriptSetSelfStarting(str);};");
    //Receive
    scriptEngine.evaluate("function receive(str){return self.scriptReceive(str);};");
    //Send
    scriptEngine.evaluate("function send(str, val){self.scriptSend(str, val);};");
    //Read file
    scriptEngine.evaluate("function readFile(str){return self.scriptReadFile(str);};");
    
    //------------------------------------------------------------------
    // EVALUATE THE SCRIPT 
    //------------------------------------------------------------------
    QScriptSyntaxCheckResult check = scriptEngine.checkSyntax(script);
    if(check.state() != QScriptSyntaxCheckResult::Valid)
    {
        std::cerr << QString("Error in script line %1, column %2: %3")
                .arg(check.errorLineNumber())
                .arg(check.errorColumnNumber())
                .arg(check.errorMessage())
                .toStdString() << std::endl;
    }
    else if(!scriptEngine.canEvaluate(script))
    {
        std::cerr << QString("Can't evaluate script: unknown error.")
                .toStdString() << std::endl;
    }
    else
    {        
        scriptEngine.evaluate(script);
        scriptEngine.evaluate("init()");
    }
}
示例#13
0
bool QtScriptFemCondition3D::setCondition(QString script)
{
    QString func = "function isApplied(x, y, z){\n";
    func += "return " + script + ";\n}";
    script_ = script;
    QScriptSyntaxCheckResult chk = QScriptEngine::checkSyntax(func);
    if (chk.state() != QScriptSyntaxCheckResult::Valid)
    {
        std::cout << "Ошибка анализа граничного условия: " << chk.errorMessage().toStdString() << std::endl;
        return false;
    }
    object_ = engine_.evaluate(func);
    if (object_.isError())return false;
    return true;
}
示例#14
0
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
    if (!entity) {
        return QScriptValue(); // no entity...
    }
    
    EntityItemID entityID = entity->getEntityItemID();
    if (_entityScripts.contains(entityID)) {
        EntityScriptDetails details = _entityScripts[entityID];
        
        // check to make sure our script text hasn't changed on us since we last loaded it
        if (details.scriptText == entity->getScript()) {
            return details.scriptObject; // previously loaded
        }
        
        // if we got here, then we previously loaded a script, but the entity's script value
        // has changed and so we need to reload it.
        _entityScripts.remove(entityID);
    }
    if (entity->getScript().isEmpty()) {
        return QScriptValue(); // no script
    }
    
    QString scriptContents = loadScriptContents(entity->getScript());
    
    QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(scriptContents);
    if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
        qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID;
        qDebug() << "   " << syntaxCheck.errorMessage() << ":"
                          << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
        qDebug() << "    SCRIPT:" << entity->getScript();
        return QScriptValue(); // invalid script
    }
    
    QScriptValue entityScriptConstructor = _entitiesScriptEngine->evaluate(scriptContents);
    
    if (!entityScriptConstructor.isFunction()) {
        qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID;
        qDebug() << "    NOT CONSTRUCTOR";
        qDebug() << "    SCRIPT:" << entity->getScript();
        return QScriptValue(); // invalid script
    }

    QScriptValue entityScriptObject = entityScriptConstructor.construct();
    EntityScriptDetails newDetails = { entity->getScript(), entityScriptObject };
    _entityScripts[entityID] = newDetails;

    return entityScriptObject; // newly constructed
}
示例#15
0
void CConsole::evaluate() {
	QScriptSyntaxCheckResult result = m_engine->checkSyntax( m_text->toPlainText() );
	switch (result.state()) {
		case QScriptSyntaxCheckResult::Valid:
			qDebug() << "Valid Syntax";
			break;
		case QScriptSyntaxCheckResult::Error:
		case QScriptSyntaxCheckResult::Intermediate:
			qDebug() << "Invalid Syntax at" << result.errorLineNumber() << result.errorMessage();
			return;
			break;
	};
	if(m_engine->canEvaluate( m_text->toPlainText() )) {
		qDebug() << "Evaluatable";
	} else {
		qDebug() << "Non-evaluatable";
	}
}
示例#16
0
void JavascriptInstance::IncludeFile(const QString &path)
{
    for(uint i = 0; i < includedFiles.size(); ++i)
        if (includedFiles[i].toLower() == path.toLower())
        {
            LogDebug("JavascriptInstance::IncludeFile: Not including already included file " + path);
            return;
        }

    QString script = LoadScript(path);

    QScriptContext *context = engine_->currentContext();
    assert(context);
    if (!context)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::currentContext() returned null!");
        return;
    }

    QScriptContext *parent = context->parentContext();
    if (!parent)
    {
        LogError("JavascriptInstance::IncludeFile: QScriptEngine::parentContext() returned null!");
        return;
    }

    context->setActivationObject(context->parentContext()->activationObject());
    context->setThisObject(context->parentContext()->thisObject());

    QScriptSyntaxCheckResult syntaxResult = engine_->checkSyntax(script);
    if(syntaxResult.state() != QScriptSyntaxCheckResult::Valid)
    {
        LogError("JavascriptInstance::IncludeFile: Syntax error in " + path + ". " + syntaxResult.errorMessage() +
            " In line:" + QString::number(syntaxResult.errorLineNumber()));
        return;
    }

    QScriptValue result = engine_->evaluate(script, path);

    includedFiles.push_back(path);
    
    if (engine_->hasUncaughtException())
        LogError(result.toString());
}
示例#17
0
void ScriptForm::accept()
{
    m_script = textEdit->toPlainText();
    QScriptEngine javaScriptParser;
    int errorLineNumber = 0;
    QString errorMessage;
#if QT_VERSION >= 0x040500
    QScriptSyntaxCheckResult syntaxResult =
            javaScriptParser.checkSyntax(m_script);
    if (syntaxResult.state() != QScriptSyntaxCheckResult::Valid) {
        errorLineNumber = syntaxResult.errorLineNumber();
        errorMessage = syntaxResult.errorMessage();
        if (errorMessage.isEmpty())
            errorMessage = tr("Syntax Error");
    }
#else
    QScriptValue value(&javaScriptParser, 0);
    javaScriptParser.globalObject().setProperty("cellRow", value);
    javaScriptParser.globalObject().setProperty("cellColumn", value);
    javaScriptParser.globalObject().setProperty("cellValue", value);
    QScriptValue result = javaScriptParser.evaluate(m_script);
    if (javaScriptParser.hasUncaughtException()) {
        errorLineNumber = javaScriptParser
                .uncaughtExceptionLineNumber();
        errorMessage = javaScriptParser.uncaughtException()
                .toString();
    }
#endif
    if (!errorMessage.isEmpty()) {
        AQP::warning(this, tr("Error"),
                tr("Invalid script on line %1:\n%2")
                   .arg(errorLineNumber).arg(errorMessage));
        QTextCursor cursor = textEdit->textCursor();
        cursor.clearSelection();
        cursor.movePosition(QTextCursor::Start);
        cursor.movePosition(QTextCursor::Down,
                QTextCursor::MoveAnchor, errorLineNumber - 1);
        cursor.select(QTextCursor::LineUnderCursor);
        textEdit->setTextCursor(cursor);
    }
    else
        QDialog::accept();
}
void DroneshareUploadDialog::vehicleQueryComplete(const QString &jsonResponse)
{
    QLOG_DEBUG() << "droneshare: Vehicle Query Complete"/* << jsonResponse*/;

    QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(jsonResponse);
    QScriptEngine engine;
    QScriptValue result = engine.evaluate("("+jsonResponse+")");

    if (engine.hasUncaughtException()){
        QLOG_ERROR() << "Error evaluating version object";
        QLOG_ERROR() << "Error @line#" << engine.uncaughtExceptionLineNumber();
        QLOG_ERROR() << "Backtrace:" << engine.uncaughtExceptionBacktrace();
        QLOG_ERROR() << "Syntax Check:" << syntaxCheck.errorMessage();
        QLOG_ERROR() << "Syntax Check line:" << syntaxCheck.errorLineNumber()
                     << " col:" << syntaxCheck.errorColumnNumber();
        return;
    }
    ui->statusLabel->setText("Vehicle Query Complete.");
    QMap<QString,QString> vehicleList;

    QScriptValue entries = result.property("vehicles");
    QScriptValueIterator it(entries);
    while (it.hasNext()){
        it.next();
        QScriptValue entry = it.value();
        QString uuid = entry.property("uuid").toString();
        QString name = entry.property("name").toString();
        vehicleList.insert(name,uuid);
    }

    bool ok = false;
    QString item = QInputDialog::getItem(this, tr("Vehicle Selection"),tr("vehicle"),vehicleList.keys(),1,
                                                          false, &ok, Qt::Dialog, Qt::ImhNone);
    if (ok){
        startLogUpload(vehicleList.value(item));
    }

    m_droneshareQuery->deleteLater();
    m_droneshareQuery = NULL;
}
void BluemonkeySink::writeProgram(QString program)
{
	QScriptSyntaxCheckResult result = QScriptEngine::checkSyntax(program);
	if(result.state() != QScriptSyntaxCheckResult::Valid)
	{
		DebugOut(DebugOut::Error)<<"Syntax error in program: "<<result.errorMessage().toStdString()<<endl;
		return;
	}

	QFile file(configuration["customPrograms"].c_str());

	if(!file.open(QIODevice::ReadWrite | QIODevice::Append))
	{
		DebugOut(DebugOut::Error)<<"failed to open file: "<<file.fileName().toStdString()<<endl;
		return;
	}

	file.write(program.toUtf8());
	file.write("\n");

	file.close();
}
示例#20
0
bool ScriptManager::AddScript(QString script, QString name) {
    if(name == "") {
        Logger::Get().Error("Cannot add script without name.");
        return false;
    }

    if(HasScript(name)) {
        Logger::Get().Error("Cannot add script \"" + name + "\": a script with this name already exists.");
        return false;
    }

    // check the syntax
    QScriptSyntaxCheckResult syntax = mScriptEngine->checkSyntax(script);
    if(syntax.state() != QScriptSyntaxCheckResult::Valid) {
        Logger::Get().Error("Syntax error in script \"" + name + "\" at line "
                            + Utils::ToString(syntax.errorLineNumber()) + " column "
                            + Utils::ToString(syntax.errorColumnNumber()) + ":");
        Logger::Get().Error("    " +  syntax.errorMessage());
    } else {
        Logger::Get().Debug("Adding script \"" + name + "\".");
        mScripts[name] = QScriptProgram(script, name);
    }
    return true;
}
void DroneshareUploadDialog::uploadComplete(const QString& jsonResponse)
{
    QLOG_DEBUG() << "droneshare: upload success: " << jsonResponse;
    m_droneshareUpload->deleteLater();
    m_droneshareUpload = NULL;

    QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(jsonResponse);
    QScriptEngine engine;
    QScriptValue result = engine.evaluate("("+jsonResponse+")");

    if (engine.hasUncaughtException()){
        QLOG_ERROR() << "Error evaluating version object";
        QLOG_ERROR() << "Error @line#" << engine.uncaughtExceptionLineNumber();
        QLOG_ERROR() << "Backtrace:" << engine.uncaughtExceptionBacktrace();
        QLOG_ERROR() << "Syntax Check:" << syntaxCheck.errorMessage();
        QLOG_ERROR() << "Syntax Check line:" << syntaxCheck.errorLineNumber()
                     << " col:" << syntaxCheck.errorColumnNumber();
        return;
    }

    QString viewURL = result.property(0).property("viewURL").toString();
    ui->statusLabel->setOpenExternalLinks(true);
    ui->statusLabel->setText(tr("<html><head/><body><p>Upload Suceeded!<br><a href=\"%1\"><span style=\" text-decoration: underline; color:#0000ff;\">Click to view on Droneshare</span></a></p></body></html>").arg(viewURL));
}
示例#22
0
void VtlWidget::setScriptText(const QString& txt)
{
  script_text = txt;

  QScriptSyntaxCheckResult res = QScriptEngine::checkSyntax (script_text);

  if ( res.state() != QScriptSyntaxCheckResult::Valid ) {
    qWarning () << res.errorMessage();
  }
  else {
    QScriptValue res = script_engine.evaluate (script_text);
    if ( script_engine.hasUncaughtException() ) {
      qWarning() << "1: script have uncaught exception: line no:" << script_engine.uncaughtExceptionLineNumber() << ":" << res.toString();
    }
    else {
      QScriptValue script_widget = script_engine.newQObject(this);
      QScriptValue init_res      = script_engine.globalObject().property("init").call( QScriptValue(),  QScriptValueList() << script_widget );

      if ( script_engine.hasUncaughtException() ) {
          qWarning() << "2: script have uncaught exception: line no:" << script_engine.uncaughtExceptionLineNumber() << ":" << init_res.toString();
      }
    }
  }
}
bool QtScriptForceCondition3D::setCondition(QString condition, QString u, QString v, QString w)
{
    QString func = "function isApplied(x, y, z){\n";
    func += "return " + condition + ";\n}\n";
    func += "function u(x, y, z){\n";
    func += "return " + u + ";\n}\n";
    func += "function v(x, y, z){\n";
    func += "return " + v + ";\n}\n";
    func += "function w(x, y, z){\n";
    func += "return " + w + ";\n}\n";
    condition_ = condition;
    u_ = u;
    v_ = v;
    w_ = w;
    QScriptSyntaxCheckResult chk = QScriptEngine::checkSyntax(func);
    if (chk.state() != QScriptSyntaxCheckResult::Valid)
    {
        std::cout << "Ошибка анализа граничного условия: " << chk.errorMessage().toStdString() << std::endl;
        return false;
    }
    object_ = engine_.evaluate(func);
    if (object_.isError())return false;
    return true;
}
void DroneshareUploadDialog::uploadFailed(const QString& jsonResponse, const QString& errorString)
{
    QLOG_DEBUG() << "droneshare: upload failed: " << errorString
                    << "JSON response:" << jsonResponse;
    m_droneshareUpload->deleteLater();
    m_droneshareUpload = NULL;

    QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(jsonResponse);
    QScriptEngine engine;
    QScriptValue result = engine.evaluate("("+jsonResponse+")");

    if (engine.hasUncaughtException()){
        QLOG_ERROR() << "Error evaluating version object";
        QLOG_ERROR() << "Error @line#" << engine.uncaughtExceptionLineNumber();
        QLOG_ERROR() << "Backtrace:" << engine.uncaughtExceptionBacktrace();
        QLOG_ERROR() << "Syntax Check:" << syntaxCheck.errorMessage();
        QLOG_ERROR() << "Syntax Check line:" << syntaxCheck.errorLineNumber()
                     << " col:" << syntaxCheck.errorColumnNumber();
        return;
    }

    QString message = result.property("message").toString();
    ui->statusLabel->setText(tr("Upload Failed!\n%1").arg(message));
}
示例#25
0
void ScriptParametersDialog::accept()
{
	int rowCount = ui->parameterTable->rowCount();

	QScriptEngine scriptEngine;

	mScript->removeAllParameters();

	for(int row = 0; row < rowCount; ++row)
	{
		QWidget *widget = ui->parameterTable->cellWidget(row, 0);
		if(!widget)
			continue;

		QLineEdit *nameLineEdit = qobject_cast<QLineEdit *>(widget);

		widget = ui->parameterTable->cellWidget(row, 1);
		if(!widget)
			continue;

		if(nameLineEdit->text().isEmpty())
			continue;

		QRegExp nameRegExp("[a-z_][a-z0-9_]*", Qt::CaseInsensitive);
		if(!nameRegExp.exactMatch(nameLineEdit->text()))
		{
			QMessageBox::warning(this, tr("Script parameter error"), tr("Incorrect parameter name \"%1\".")
				.arg(nameLineEdit->text()));
			nameLineEdit->setFocus();

			return;
		}

		bool isCode = false;
		QString value;

		switch(mParameterTypes.at(row))
		{
		case ActionTools::ScriptParameter::Text:
			{
				ActionTools::CodeLineEdit *valueWidget = qobject_cast<ActionTools::CodeLineEdit *>(widget);

				isCode = valueWidget->isCode();
				value = valueWidget->text();
			}
			break;
		case ActionTools::ScriptParameter::Number:
			{
				ActionTools::CodeSpinBox *valueWidget = qobject_cast<ActionTools::CodeSpinBox *>(widget);

				isCode = valueWidget->isCode();
				value = valueWidget->text();
			}
			break;
		case ActionTools::ScriptParameter::Window:
			{
				ActionTools::WindowEdit *valueWidget = qobject_cast<ActionTools::WindowEdit *>(widget);

				isCode = valueWidget->isCode();
				value = valueWidget->text();
			}
			break;
		case ActionTools::ScriptParameter::File:
			{
				ActionTools::FileEdit *valueWidget = qobject_cast<ActionTools::FileEdit *>(widget);

				isCode = valueWidget->isCode();
				value = valueWidget->text();
			}
			break;
		case ActionTools::ScriptParameter::Line:
			{
				ActionTools::LineComboBox *valueWidget = qobject_cast<ActionTools::LineComboBox *>(widget);

				isCode = valueWidget->isCode();
				value = valueWidget->codeLineEdit()->text();
			}
			break;
		}

		if(isCode)
		{
			QScriptSyntaxCheckResult result = scriptEngine.checkSyntax(value);
			if(result.state() != QScriptSyntaxCheckResult::Valid)
			{
				QMessageBox::warning(this, tr("Script parameter error"), tr("The script parameter named \"%1\" contains an error: \"%2\", please correct it.")
					.arg(nameLineEdit->text())
					.arg(result.errorMessage()));
				widget->setFocus();

				return;
			}
		}

		mScript->addParameter(ActionTools::ScriptParameter(nameLineEdit->text(), value, isCode, mParameterTypes.at(row)));
	}

	QDialog::accept();
}
示例#26
0
int main( int argc, char ** argv )
{
	QApplication::setColorSpec( QApplication::CustomColor );

    QApplication a( argc, argv );
	a.setApplicationVersion( APP_VERSION );

    QSplashScreen* splash = new QSplashScreen;
    splash->setPixmap( QPixmap(":/icons/tonatiuhsplash.png") );
    splash->show();

    Qt::Alignment topRight = Qt::AlignRight | Qt::AlignTop;

    splash->showMessage(QObject::tr("Loading libraries..."), topRight, Qt::black);


    QApplication::addLibraryPath( QApplication::applicationDirPath()
	        + QDir::separator() + "marble" );

	SoQt::init( (QWidget *) NULL );

	//MFVec2::initClass();
	UserMField::initClass();
	UserSField::initClass();
	TSceneKit::initClass();
	TMaterial::initClass();
	TDefaultMaterial::initClass();
	TSeparatorKit::initClass();
	TShape::initClass();
	TCube::initClass();
	TLightShape::initClass();
	TShapeKit::initClass();
	TAnalyzerKit::initClass();
	TAnalyzerResultKit::initClass();
	TAnalyzerParameter::initClass();
	TAnalyzerResult::initClass();
	TAnalyzerLevel::initClass();
	TSquare::initClass();
	TLightKit::initClass();
	TSunShape::initClass();
	TDefaultSunShape::initClass();
	TTracker::initClass();
	TTrackerForAiming::initClass();
	TDefaultTracker::initClass();
	TSceneTracker::initClass();
	GraphicRootTracker::initClass();
	TTransmissivity::initClass();
	TDefaultTransmissivity::initClass();


	splash->showMessage( QObject::tr("Setting up the main window..."), topRight, Qt::black );


	QDir pluginsDirectory( qApp->applicationDirPath() );
	pluginsDirectory.cd( "plugins" );
	PluginManager pluginManager;
	pluginManager.LoadAvailablePlugins( pluginsDirectory );

    int exit;
   	if( argc > 1 )
   	{
   		QString tonatiuhFile = argv[1];

    	QFileInfo fileInfo( tonatiuhFile );
    	if( fileInfo.completeSuffix() == QLatin1String( "tnhs") )
    	{

    		QString fileName( argv[1] );
    		QFileInfo fileInfo( fileName );

    		QDir testDirectory( fileInfo.absolutePath() );
    		testDirectory.cd( "." );

    		QScriptEngine* interpreter = new QScriptEngine;
    		qScriptRegisterSequenceMetaType<QVector<QVariant> >(interpreter);


    		MainWindow* mw = new MainWindow( QLatin1String("") );
    		mw->SetPluginManager( &pluginManager );
    		QScriptValue tonatiuh = interpreter->newQObject( mw );
    		interpreter->globalObject().setProperty( "tonatiuh", tonatiuh );


    		QFile scriptFile( fileName );
    		if( !scriptFile.open( QIODevice::ReadOnly) )
    		{
    			QString errorMessage = QString( "Cannot open file %1." ).arg( fileName );
    			std::cerr<<errorMessage.toStdString()<<std::endl;
    		}


    		QTextStream in( &scriptFile );
    		QString program = in.readAll();
    		scriptFile.close();


    		QScriptSyntaxCheckResult checkResult = interpreter->checkSyntax( program );
    		if( checkResult.state() != QScriptSyntaxCheckResult::Valid )
    		{
    			QString errorMessage = QString( "Script Syntaxis Error.\n"
    					"Line: %1. %2" ).arg( QString::number( checkResult.errorLineNumber() ), checkResult.errorMessage () );
    			std::cerr<<errorMessage.toStdString()<<std::endl;
    			return -1;
    		}

    		QScriptValue result = interpreter->evaluate( program );
    		if( result.isError () )
    		{
    			QScriptValue lineNumber = result.property( "lineNumber");

    			QString errorMessage = QString( "Script Execution Error.\nLine %1. %2" ).arg( QString::number( lineNumber.toNumber() ), result.toString() );
    			std::cerr<<errorMessage.toStdString()<<std::endl;
    			return -1;

    		}

       		delete mw;
       		delete interpreter;
    		exit = 0;
    	}
    	else
    	{

    		MainWindow* mw = new MainWindow( tonatiuhFile );
    		mw->SetPluginManager( &pluginManager );


       		mw->show();
       	    splash->finish( mw );
       	    delete splash;
    	    exit = a.exec();
       		delete mw;
    	}
   	}
   	else
   	{
   		MainWindow* mw = new MainWindow("");
		mw->SetPluginManager( &pluginManager );
   		mw->show();
   	    splash->finish( mw );
   	    delete splash;
	    exit = a.exec();
   		delete mw;

   	}

	return exit;
}
示例#27
0
文件: core.cpp 项目: ice2heart/calc
void Core::readyRead()
{
	QTcpSocket *socket = (QTcpSocket *) sender();
	sConStore conn = mCoreClients[socket];
	//Плохо, если кусок будет слишком большой может и не влезть
	//но так проще.
	QByteArray raw = socket->readAll();
	QJsonDocument doc = QJsonDocument::fromJson(raw);
	QJsonObject obj = doc.object();
	QJsonObject retVal;
	if (obj["name"].toString() == "eval")
	{
		QString data = obj["data"].toString();
		//Для вычисление используем qsript
		//чтоб не писать свой парсер мат строк
		QScriptEngine myEngine;
		bool historyReplaceFail = false;
		//Заменяем все H\d+ На значения из истории
		QRegExp rx("H(\\d+)");
		int pos = 0;
		while ((pos = rx.indexIn(data)) != -1 && !historyReplaceFail)
		{
			if (conn->history.contains(rx.cap(1).toInt()))
			{
				QString value = conn->history.value(rx.cap(1).toInt());
				data.replace(pos, rx.matchedLength(), value);
				pos += value.length();
			}
			else
				historyReplaceFail = true;
		}
		QScriptSyntaxCheckResult res = myEngine.checkSyntax(data);
		if (historyReplaceFail)
		{
			error("History replace error "+data);
			retVal["name"] = "error";
			retVal["text"] = "History replace error";
		}
		else if (res.state() != QScriptSyntaxCheckResult::Valid)
		{
			error("error expression "+data);
			retVal["name"] = "error";
			retVal["text"] = "Error string";
		}
		else
		{
			QJsonArray jsonArray;
			QJsonObject eResult;

			QString result = myEngine.evaluate(data).toString();
			int count = conn->addEvalResult(result);
			log(QString("Eval %1 result is %2").arg(data, result));
			retVal["name"] = "eval_results";
			eResult["num"] = count;
			eResult["result"] = result;
			jsonArray.append(eResult);
			retVal["results"] = jsonArray;
		}
	}
	else if (obj["name"].toString() == "get_history")
	{
		log("Get history request");
		QJsonArray jsonArray;
		foreach (int num, conn->history.keys()) {
			QJsonObject result;
			result["num"] = num;
			result["result"] = conn->history[num];
			jsonArray.append(result);
		}
		retVal["name"] = "eval_results";
		retVal["results"] = jsonArray;
	}
示例#28
0
bool testPlayerScript(QString path, int player, int difficulty)
{
	QScriptEngine *engine = new QScriptEngine();
	QFile input(path);
	input.open(QIODevice::ReadOnly);
	QString source(QString::fromUtf8(input.readAll()));
	input.close();

	// Special functions
	engine->globalObject().setProperty("setTimer", engine->newFunction(js_setTimer));
	engine->globalObject().setProperty("queue", engine->newFunction(js_queue));
	engine->globalObject().setProperty("removeTimer", engine->newFunction(js_removeTimer));
	engine->globalObject().setProperty("include", engine->newFunction(js_include));
	engine->globalObject().setProperty("bind", engine->newFunction(js_bind));

	// Special global variables
	engine->globalObject().setProperty("version", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("selectedPlayer", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("gameTime", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("difficulty", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("mapName", "TEST", QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("baseType", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("alliancesType", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("powerType", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("maxPlayers", CUR_PLAYERS, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("scavengers", true, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("mapWidth", 80, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("mapHeight", 80, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Most special global
	engine->globalObject().setProperty("me", player, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Register functions to the script engine here
	engine->globalObject().setProperty("_", engine->newFunction(js_translate));
	engine->globalObject().setProperty("label", engine->newFunction(js_label));
	engine->globalObject().setProperty("enumLabels", engine->newFunction(js_enumLabels));
	engine->globalObject().setProperty("enumGateways", engine->newFunction(js_enumGateways));

	// horrible hacks follow -- do not rely on these being present!
	engine->globalObject().setProperty("hackNetOff", engine->newFunction(js_hackNetOff));
	engine->globalObject().setProperty("hackNetOn", engine->newFunction(js_hackNetOn));
	engine->globalObject().setProperty("objFromId", engine->newFunction(js_objFromId));

	// General functions -- geared for use in AI scripts
	engine->globalObject().setProperty("debug", engine->newFunction(js_debug));
	engine->globalObject().setProperty("console", engine->newFunction(js_console));
	engine->globalObject().setProperty("structureIdle", engine->newFunction(js_structureIdle));
	engine->globalObject().setProperty("enumStruct", engine->newFunction(js_enumStruct));
	engine->globalObject().setProperty("enumStructOffWorld", engine->newFunction(js_enumStructOffWorld));
	engine->globalObject().setProperty("enumDroid", engine->newFunction(js_enumDroid));
	engine->globalObject().setProperty("enumGroup", engine->newFunction(js_enumGroup));
	engine->globalObject().setProperty("enumFeature", engine->newFunction(js_enumFeature));
	engine->globalObject().setProperty("enumBlips", engine->newFunction(js_enumBlips));
	engine->globalObject().setProperty("enumResearch", engine->newFunction(js_enumResearch));
	engine->globalObject().setProperty("getResearch", engine->newFunction(js_getResearch));
	engine->globalObject().setProperty("pursueResearch", engine->newFunction(js_pursueResearch));
	engine->globalObject().setProperty("distBetweenTwoPoints", engine->newFunction(js_distBetweenTwoPoints));
	engine->globalObject().setProperty("newGroup", engine->newFunction(js_newGroup));
	engine->globalObject().setProperty("groupAddArea", engine->newFunction(js_groupAddArea));
	engine->globalObject().setProperty("groupAddDroid", engine->newFunction(js_groupAddDroid));
	engine->globalObject().setProperty("groupSize", engine->newFunction(js_groupSize));
	engine->globalObject().setProperty("orderDroidLoc", engine->newFunction(js_orderDroidLoc));
	engine->globalObject().setProperty("playerPower", engine->newFunction(js_playerPower));
	engine->globalObject().setProperty("isStructureAvailable", engine->newFunction(js_isStructureAvailable));
	engine->globalObject().setProperty("pickStructLocation", engine->newFunction(js_pickStructLocation));
	engine->globalObject().setProperty("droidCanReach", engine->newFunction(js_droidCanReach));
	engine->globalObject().setProperty("orderDroidStatsLoc", engine->newFunction(js_orderDroidBuild)); // deprecated
	engine->globalObject().setProperty("orderDroidBuild", engine->newFunction(js_orderDroidBuild));
	engine->globalObject().setProperty("orderDroidObj", engine->newFunction(js_orderDroidObj));
	engine->globalObject().setProperty("orderDroid", engine->newFunction(js_orderDroid));
	engine->globalObject().setProperty("buildDroid", engine->newFunction(js_buildDroid));
	engine->globalObject().setProperty("addDroid", engine->newFunction(js_addDroid));
	engine->globalObject().setProperty("addFeature", engine->newFunction(js_addFeature));
	engine->globalObject().setProperty("componentAvailable", engine->newFunction(js_componentAvailable));
	engine->globalObject().setProperty("isVTOL", engine->newFunction(js_isVTOL));
	engine->globalObject().setProperty("safeDest", engine->newFunction(js_safeDest));
	engine->globalObject().setProperty("activateStructure", engine->newFunction(js_activateStructure));
	engine->globalObject().setProperty("chat", engine->newFunction(js_chat));

	// Functions that operate on the current player only
	engine->globalObject().setProperty("centreView", engine->newFunction(js_centreView));
	engine->globalObject().setProperty("playSound", engine->newFunction(js_playSound));
	engine->globalObject().setProperty("gameOverMessage", engine->newFunction(js_gameOverMessage));

	// Global state manipulation -- not for use with skirmish AI (unless you want it to cheat, obviously)
	engine->globalObject().setProperty("setStructureLimits", engine->newFunction(js_setStructureLimits));
	engine->globalObject().setProperty("applyLimitSet", engine->newFunction(js_applyLimitSet));
	engine->globalObject().setProperty("setMissionTime", engine->newFunction(js_setMissionTime));
	engine->globalObject().setProperty("setReinforcementTime", engine->newFunction(js_setReinforcementTime));
	engine->globalObject().setProperty("completeResearch", engine->newFunction(js_completeResearch));
	engine->globalObject().setProperty("enableResearch", engine->newFunction(js_enableResearch));
	engine->globalObject().setProperty("setPower", engine->newFunction(js_setPower));
	engine->globalObject().setProperty("setTutorialMode", engine->newFunction(js_setTutorialMode));
	engine->globalObject().setProperty("setDesign", engine->newFunction(js_setDesign));
	engine->globalObject().setProperty("setMiniMap", engine->newFunction(js_setMiniMap));
	engine->globalObject().setProperty("addReticuleButton", engine->newFunction(js_addReticuleButton));
	engine->globalObject().setProperty("removeReticuleButton", engine->newFunction(js_removeReticuleButton));
	engine->globalObject().setProperty("enableStructure", engine->newFunction(js_enableStructure));
	engine->globalObject().setProperty("makeComponentAvailable", engine->newFunction(js_makeComponentAvailable));
	engine->globalObject().setProperty("enableComponent", engine->newFunction(js_enableComponent));
	engine->globalObject().setProperty("enableTemplate", engine->newFunction(js_enableTemplate));
	engine->globalObject().setProperty("allianceExistsBetween", engine->newFunction(js_allianceExistsBetween));
	engine->globalObject().setProperty("removeStruct", engine->newFunction(js_removeStruct));
	engine->globalObject().setProperty("removeObject", engine->newFunction(js_removeObject));
	engine->globalObject().setProperty("setScrollParams", engine->newFunction(js_setScrollParams));
	engine->globalObject().setProperty("addStructure", engine->newFunction(js_addStructure));
	engine->globalObject().setProperty("loadLevel", engine->newFunction(js_loadLevel));
	engine->globalObject().setProperty("setDroidExperience", engine->newFunction(js_setDroidExperience));
	engine->globalObject().setProperty("setNoGoArea", engine->newFunction(js_setNoGoArea));
	engine->globalObject().setProperty("setAlliance", engine->newFunction(js_setAlliance));
	engine->globalObject().setProperty("setAssemblyPoint", engine->newFunction(js_setAssemblyPoint));

	// Set some useful constants
	engine->globalObject().setProperty("DORDER_ATTACK", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_MOVE", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_SCOUT", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_BUILD", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_HELPBUILD", 3, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_LINEBUILD", 4, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_REPAIR", 5, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_RETREAT", 6, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_PATROL", 7, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_DEMOLISH", 8, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_EMBARK", 9, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_DISEMBARK", 10, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_FIRESUPPORT", 11, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_HOLD", 12, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_RTR", 13, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_RTB", 14, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_STOP", 15, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DORDER_REARM", 16, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("COMMAND", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("BUILD", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("MANUFACTURE", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("RESEARCH", 3, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("INTELMAP", 4, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DESIGN", 5, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("CANCEL", 6, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("CAMP_CLEAN", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("CAMP_BASE", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("CAMP_WALLS", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("NO_ALLIANCES", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("ALLIANCES", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("ALLIANCES_TEAMS", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("BEING_BUILT", SS_BEING_BUILT, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("BUILT", SS_BUILT, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("BEING_DEMOLISHED", SS_BEING_DEMOLISHED, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_CONSTRUCT", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_WEAPON", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_PERSON", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_REPAIR", 3, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_SENSOR", 4, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_ECM", 5, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_CYBORG", 6, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_TRANSPORTER", 7, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID_COMMAND", 8, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("HQ", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("FACTORY", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("POWER_GEN", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("RESOURCE_EXTRACTOR", 3, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DEFENSE", 4, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("LASSAT", 5, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("WALL", 6, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("RESEARCH_LAB", 7, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("REPAIR_FACILITY", 8, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("CYBORG_FACTORY", 9, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("VTOL_FACTORY", 10, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("REARM_PAD", 11, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("SAT_UPLINK", 12, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("GATE", 13, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("COMMAND_CONTROL", 14, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("EASY", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("MEDIUM", 1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("HARD", 2, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("INSANE", 3, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("STRUCTURE", OBJ_STRUCTURE, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("DROID", OBJ_DROID, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("FEATURE", OBJ_FEATURE, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("POSITION", POSITION, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("AREA", AREA, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("ALL_PLAYERS", -1, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("ALLIES", -2, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	QScriptValue playerData = engine->newArray(CUR_PLAYERS);
	for (int i = 0; i < CUR_PLAYERS; i++)
	{
		QScriptValue vector = engine->newObject();
		vector.setProperty("difficulty", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("colour", 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("position", i, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("team", i, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("isAI", i != 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("isHuman", i == 0, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		playerData.setProperty(i, vector, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	}
	engine->globalObject().setProperty("playerData", playerData, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Static map knowledge about start positions
	//== \item[derrickPositions] An array of derrick starting positions on the current map. Each item in the array is an
	//== object containing the x and y variables for a derrick.
	//== \item[startPositions] An array of player start positions on the current map. Each item in the array is an
	//== object containing the x and y variables for a player start position.
	QScriptValue startPositions = engine->newArray(CUR_PLAYERS);
	for (int i = 0; i < CUR_PLAYERS; i++)
	{
		QScriptValue vector = engine->newObject();
		vector.setProperty("x", 40, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("y", 40, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		startPositions.setProperty(i, vector, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	}
	QScriptValue derrickPositions = engine->newArray(6);
	for (int i = 0; i < 6; i++)
	{
		QScriptValue vector = engine->newObject();
		vector.setProperty("x", 40, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		vector.setProperty("y", 40, QScriptValue::ReadOnly | QScriptValue::Undeletable);
		derrickPositions.setProperty(i, vector, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	}
	engine->globalObject().setProperty("derrickPositions", derrickPositions, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	engine->globalObject().setProperty("startPositions", startPositions, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	QScriptSyntaxCheckResult syntax = QScriptEngine::checkSyntax(source);
	if (syntax.state() != QScriptSyntaxCheckResult::Valid)
	{
		qFatal("Syntax error in %s line %d: %s", path.toUtf8().constData(), syntax.errorLineNumber(), syntax.errorMessage().toUtf8().constData());
		return false;
	}
	QScriptValue result = engine->evaluate(source, path);
	if (engine->hasUncaughtException())
	{
		int line = engine->uncaughtExceptionLineNumber();
		qFatal("Uncaught exception at line %d, file %s: %s", line, path.toUtf8().constData(), result.toString().toUtf8().constData());
		return false;
	}

	// Call init
	callFunction(engine, "eventGameInit", QScriptValueList());

	// Now set gameTime to something proper
	engine->globalObject().setProperty("gameTime", 10101, QScriptValue::ReadOnly | QScriptValue::Undeletable);

	callFunction(engine, "eventStartLevel", QScriptValueList());
	callFunction(engine, "eventLaunchTransporter", QScriptValueList());
	callFunction(engine, "eventReinforcementsArrived", QScriptValueList());
	callFunction(engine, "eventMissionTimeout", QScriptValueList());
	callFunction(engine, "eventVideoDone", QScriptValueList());

	// Call other events
	{
		QScriptValueList args;
		args += convDroid(engine);
		args += convStructure(engine);
		callFunction(engine, "eventDroidBuilt", args);
	}
	{
		QScriptValueList args;
		args += convStructure(engine);
		args += convObj(engine);
		callFunction(engine, "eventStructureAttacked", args);
	}
	{
		QScriptValueList args;
		args += convResearch(engine);
		args += convStructure(engine);
		callFunction(engine, "eventResearched", args);
	}
	{
		QScriptValueList args;
		args += convObj(engine);
		args += convObj(engine);
		callFunction(engine, "eventAttacked", args);
	}
	{
		QScriptValueList args;
		args += convStructure(engine);
		args += convDroid(engine);
		callFunction(engine, "eventStructureBuilt", args);
	}
	{
		QScriptValueList args;
		args += convDroid(engine);
		callFunction(engine, "eventDroidIdle", args);
	}
	{
		QScriptValueList args;
		args += QScriptValue(0);
		args += QScriptValue(1);
		args += QScriptValue("message");
		callFunction(engine, "eventChat", args);
	}
	{
		QScriptValueList args;
		args += convObj(engine);
		args += convObj(engine);
		callFunction(engine, "eventObjectSeen", args);
	}

	// Now test timers
	// TODO -- implement object parameters
	for (int i = 0; i < timers.size(); ++i)
	{
		timerNode node = timers.at(i);
		callFunction(node.engine, node.function, QScriptValueList(), true);
	}

	// Clean up
	delete engine;
	timers.clear();
	return true;
}
示例#29
0
bool loadPlayerScript(QString path, int player, int difficulty)
{
	ASSERT_OR_RETURN(false, player < MAX_PLAYERS, "Player index %d out of bounds", player);
	QScriptEngine *engine = new QScriptEngine();
	UDWORD size;
	char *bytes = NULL;
	if (!loadFile(path.toAscii().constData(), &bytes, &size))
	{
		debug(LOG_ERROR, "Failed to read script file \"%s\"", path.toAscii().constData());
		return false;
	}
	QString source = QString::fromAscii(bytes, size);
	free(bytes);
	QScriptSyntaxCheckResult syntax = QScriptEngine::checkSyntax(source);
	ASSERT_OR_RETURN(false, syntax.state() == QScriptSyntaxCheckResult::Valid, "Syntax error in %s line %d: %s", 
	                 path.toAscii().constData(), syntax.errorLineNumber(), syntax.errorMessage().toAscii().constData());
	// Special functions
	engine->globalObject().setProperty("setTimer", engine->newFunction(js_setTimer));
	engine->globalObject().setProperty("queue", engine->newFunction(js_queue));
	engine->globalObject().setProperty("removeTimer", engine->newFunction(js_removeTimer));
	engine->globalObject().setProperty("include", engine->newFunction(js_include));
	engine->globalObject().setProperty("bind", engine->newFunction(js_bind));

	// Special global variables
	//== \item[version] Current version of the game, set in \emph{major.minor} format.
	engine->globalObject().setProperty("version", "3.2", QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[selectedPlayer] The player ontrolled by the client on which the script runs.
	engine->globalObject().setProperty("selectedPlayer", selectedPlayer, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[gameTime] The current game time. Updated before every invokation of a script.
	engine->globalObject().setProperty("gameTime", gameTime, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[difficulty] The currently set campaign difficulty, or the current AI's difficulty setting. It will be one of
	//== EASY, MEDIUM, HARD or INSANE.
	engine->globalObject().setProperty("difficulty", difficulty, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[mapName] The name of the current map.
	engine->globalObject().setProperty("mapName", game.map, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[baseType] The type of base that the game starts with. It will be one of CAMP_CLEAN, CAMP_BASE or CAMP_WALLS.
	engine->globalObject().setProperty("baseType", game.base, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[alliancesType] The type of alliances permitted in this game. It will be one of NO_ALLIANCES, ALLIANCES or ALLIANCES_TEAMS.
	engine->globalObject().setProperty("alliancesType", game.alliance, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[powerType] The power level set for this game.
	engine->globalObject().setProperty("powerType", game.power, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[maxPlayers] The number of active players in this game.
	engine->globalObject().setProperty("maxPlayers", game.maxPlayers, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[scavengers] Whether or not scavengers are activated in this game.
	engine->globalObject().setProperty("scavengers", game.scavengers, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[mapWidth] Width of map in tiles.
	engine->globalObject().setProperty("mapWidth", mapWidth, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[mapHeight] Height of map in tiles.
	engine->globalObject().setProperty("mapHeight", mapHeight, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	//== \item[scavengerPlayer] Index of scavenger player. (3.2+ only)
	engine->globalObject().setProperty("scavengerPlayer", scavengerPlayer(), QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Regular functions
	registerFunctions(engine);

	// Remember internal, reserved names
	QScriptValueIterator it(engine->globalObject());
	while (it.hasNext())
	{
		it.next();
		internalNamespace.insert(it.name(), 1);
	}
	// We need to always save the 'me' special variable.
	//== \item[me] The player the script is currently running as.
	engine->globalObject().setProperty("me", player, QScriptValue::ReadOnly | QScriptValue::Undeletable);
	QScriptValue result = engine->evaluate(source, path);
	ASSERT_OR_RETURN(false, !engine->hasUncaughtException(), "Uncaught exception at line %d, file %s: %s", 
	                 engine->uncaughtExceptionLineNumber(), path.toAscii().constData(), result.toString().toAscii().constData());

	// We also need to save the special 'scriptName' variable.
	//== \item[scriptName] Base name of the script that is running.
	QFileInfo basename(path);
	engine->globalObject().setProperty("scriptName", basename.baseName(), QScriptValue::ReadOnly | QScriptValue::Undeletable);

	// Register script
	scripts.push_back(engine);

	debug(LOG_SAVE, "Created script engine %d for player %d from %s", scripts.size() - 1, player, path.toUtf8().constData());
	return true;
}
示例#30
0
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity) {
    if (!entity) {
        return QScriptValue(); // no entity...
    }

    // NOTE: we keep local variables for the entityID and the script because
    // below in loadScriptContents() it's possible for us to execute the
    // application event loop, which may cause our entity to be deleted on
    // us. We don't really need access the entity after this point, can
    // can accomplish all we need to here with just the script "text" and the ID.
    EntityItemID entityID = entity->getEntityItemID();
    QString entityScript = entity->getScript();

    if (_entityScripts.contains(entityID)) {
        EntityScriptDetails details = _entityScripts[entityID];

        // check to make sure our script text hasn't changed on us since we last loaded it
        if (details.scriptText == entityScript) {
            return details.scriptObject; // previously loaded
        }

        // if we got here, then we previously loaded a script, but the entity's script value
        // has changed and so we need to reload it.
        _entityScripts.remove(entityID);
    }
    if (entityScript.isEmpty()) {
        return QScriptValue(); // no script
    }

    bool isURL = false; // loadScriptContents() will tell us if this is a URL or just text.
    QString scriptContents = loadScriptContents(entityScript, isURL);

    QScriptSyntaxCheckResult syntaxCheck = QScriptEngine::checkSyntax(scriptContents);
    if (syntaxCheck.state() != QScriptSyntaxCheckResult::Valid) {
        qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID;
        qDebug() << "   " << syntaxCheck.errorMessage() << ":"
                 << syntaxCheck.errorLineNumber() << syntaxCheck.errorColumnNumber();
        qDebug() << "    SCRIPT:" << entityScript;
        return QScriptValue(); // invalid script
    }

    if (isURL) {
        _entitiesScriptEngine->setParentURL(entity->getScript());
    }
    QScriptValue entityScriptConstructor = _sandboxScriptEngine->evaluate(scriptContents);

    if (!entityScriptConstructor.isFunction()) {
        qDebug() << "EntityTreeRenderer::loadEntityScript() entity:" << entityID;
        qDebug() << "    NOT CONSTRUCTOR";
        qDebug() << "    SCRIPT:" << entityScript;
        return QScriptValue(); // invalid script
    } else {
        entityScriptConstructor = _entitiesScriptEngine->evaluate(scriptContents);
    }

    QScriptValue entityScriptObject = entityScriptConstructor.construct();
    EntityScriptDetails newDetails = { entityScript, entityScriptObject };
    _entityScripts[entityID] = newDetails;

    if (isURL) {
        _entitiesScriptEngine->setParentURL("");
    }

    return entityScriptObject; // newly constructed
}