NResponse & NTcpServerSocketMusicServices::getYear(const NClientSession & session,
                                                      NResponse & response)
{
    bool ok;
    QString search = session.url().queryItemValue("search");
    QStringList searches = search.split("+", QString::SkipEmptyParts);
    searches = NConvert_n::fromUTF8PercentEncoding(searches);
    int start = session.url().queryItemValue("start").toInt();
    int limit  = session.url().queryItemValue("limit").toInt(&ok);
    if (!ok)
        limit = 25;
    QString dir = session.url().queryItemValue("dir");

    const NTcpServerAuthSession authSession = getAuthServices().getSession(session.sessionId());
    logMessage(session.socket()->peerAddress().toString(),
          QString("%1 is looking for year: \"%2\"; start: %3; limit: %4, dir:\"%5\"").
          arg(authSession.login()).arg(NConvert_n::fromUTF8PercentEncoding(search)).arg(start).arg(limit).arg(dir));


    int totalCount = NMDB.getYearListCount(searches);
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();
    QScriptValue svData = se.newArray(totalCount);
    svRoot.setProperty(RSP_DATA, svData);

    bool succeed = NMDB.getYearList(se, svData, totalCount, searches, start,
                                        limit, dir);
    setJsonRootReponse(svRoot, totalCount, succeed);

    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
// Configuration
NResponse & NTcpServerSocketCfgServices::getSharedDir(const NClientSession &, NResponse & response)
{
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();

    NDirList sd = NConfig::instance().sharedDirectories();
    int count = sd.count();
    svRoot.setProperty(RSP_SUCCESS , QScriptValue(count > 0));
    svRoot.setProperty(RSP_MSG, QScriptValue(count > 0 ? RSP_MSG_LOADED : RSP_MSG_NO_RESULTS));
    svRoot.setProperty(RSP_COUNT, QScriptValue(count));

    QScriptValue svData = se.newArray(count);
    svRoot.setProperty(RSP_DATA, svData);
    for(int i = 0; i < count; i++)
    {
        NDir dir = sd.at(i);
        QScriptValue svDir = se.newObject();
        svData.setProperty(i, svDir);
        svDir.setProperty("id", i);
        svDir.setProperty("path", dir.path());
        svDir.setProperty("recursive", dir.recursive());
        svDir.setProperty("shared", dir.shared());
        svDir.setProperty("exists", dir.exists());
    }
    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
NResponse & NTcpServerSocketCfgServices::postSharedDir(const NClientSession & session, NResponse & response)
{
    //logDebug("NTcpServerSocketCfgServices::svcPostSharedDir", session.postData());

    QScriptEngine se;
    se.evaluate("var data = " + QString::fromUtf8(session.content()));
    QScriptValue svReadData = se.globalObject().property("data").property("data");
    NDir dir = NDir(svReadData.property("path").toString(),
                    svReadData.property("recursive").toBool(),
                    svReadData.property("shared").toBool());

    int id  = getConfig().addSharedDirectory(dir);

    QScriptValue svRoot = se.newObject();
    svRoot.setProperty(RSP_SUCCESS , QScriptValue(true));
    svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_LOADED));

    // we add new user to response
    QScriptValue svData = se.newArray(1);
    svRoot.setProperty(RSP_DATA, svData);
    QScriptValue svDir = se.newObject();
    svData.setProperty(0, svDir);
    svDir.setProperty("id", id);
    svDir.setProperty("path", dir.path());
    svDir.setProperty("recursive", dir.recursive());
    svDir.setProperty("shared", dir.shared());
    svDir.setProperty("exists", dir.exists());
    //logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
예제 #4
0
QScriptValue variantListToScriptValue(QVariantList& variantList, QScriptEngine& scriptEngine) {

    QScriptValue scriptValue = scriptEngine.newArray();

    for (int i = 0; i < variantList.size(); i++) {
        scriptValue.setProperty(i, variantToScriptValue(variantList[i], scriptEngine));
    }

    return scriptValue;
}
예제 #5
0
QScriptValue CreateValue(const QVariant& value, QScriptEngine& engine)
{
	if(value.type() == QVariant::Map)
	{
		QScriptValue obj = engine.newObject();

		QVariantMap map = value.toMap();
		QVariantMap::const_iterator it = map.begin();
		QVariantMap::const_iterator end = map.end();
		while(it != end)
		{
			obj.setProperty( it.key(), ::CreateValue(it.value(), engine) );
			++it;
		}

		return obj;
	}

	if(value.type() == QVariant::List)
	{
		QVariantList list = value.toList();
		QScriptValue array = engine.newArray(list.length());
		for(int i=0; i<list.count(); i++)
			array.setProperty(i, ::CreateValue(list.at(i),engine));

		return array;
	}

	switch(value.type())
	{
	case QVariant::String:
		return QScriptValue(value.toString());
	case QVariant::Int:
		return QScriptValue(value.toInt());
	case QVariant::UInt:
		return QScriptValue(value.toUInt());
	case QVariant::Bool:
		return QScriptValue(value.toBool());
	case QVariant::ByteArray:
		return QScriptValue(QLatin1String(value.toByteArray()));
	case QVariant::Double:
		return QScriptValue((qsreal)value.toDouble());
	default:
		break;
	}

	if(value.isNull())
		return QScriptValue(QScriptValue::NullValue);

	return engine.newVariant(value);
}
void tst_QScriptValueIterator::iterateArrayAndRemoveAllElements()
{
    QScriptEngine engine;
    QScriptValue array = engine.newArray();
    for (int i = 0; i < 20000; ++i)
        array.setProperty(i, i);
    QBENCHMARK {
        QScriptValueIterator it(array);
        while (it.hasNext()) {
            it.next();
            it.remove();
        }
    }
}
예제 #7
0
void QFormScriptRunner::QFormScriptRunnerPrivate::initializeEngine(QWidget *w, const WidgetList &children, QScriptEngine &scriptEngine) {
    // Populate the script variables. This pushes a context which must be popped.
    QScriptContext *ctx = scriptEngine.pushContext();
    QScriptValue widgetObject =  scriptEngine.newQObject(w);
    QScriptValue childrenArray = scriptEngine.newArray (children.size());

    for(int i = 0; i < children.size(); i++) {
        childrenArray.setProperty(i, scriptEngine.newQObject(children[i]));
    }

    const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
    ctx ->activationObject().setProperty(strings.scriptWidgetVariable, widgetObject);
    ctx ->activationObject().setProperty(strings.scriptChildWidgetsVariable, childrenArray);
}
void tst_QScriptValueIterator::iterateArrayAndDoubleElements()
{
    QScriptEngine engine;
    QScriptValue array = engine.newArray();
    for (int i = 0; i < 20000; ++i)
        array.setProperty(i, i);
    QBENCHMARK {
        QScriptValueIterator it(array);
        while (it.hasNext()) {
            it.next();
            it.setValue(QScriptValue(&engine, it.value().toNumber() * 2));
        }
    }
}
void tst_QScriptValueIterator::iterateArrayAndConvertNameToIndex()
{
    QScriptEngine engine;
    QScriptValue array = engine.newArray();
    for (int i = 0; i < 20000; ++i)
        array.setProperty(i, i);
    QBENCHMARK {
        QScriptValueIterator it(array);
        while (it.hasNext()) {
            it.next();
            it.scriptName().toArrayIndex();
        }
    }
}
NResponse & NTcpServerSocketMusicServices::getAlbum(const NClientSession & session,
                                                       NResponse & response)
{
    bool ok;
    QString search = session.url().queryItemValue("search");
    QStringList searches = search.split("+", QString::SkipEmptyParts);
    searches = NConvert_n::fromUTF8PercentEncoding(searches);
    int start = session.url().queryItemValue("start").toInt();
    int limit = session.url().queryItemValue("limit").toInt(&ok);
    if (!ok)
        limit = 25;
    QString dir = session.url().queryItemValue("dir");
    QString artist;
    if(session.url().hasQueryItem("artist"))// Cos of NULL test
    {
        artist = session.url().queryItemValue("artist");
        if (artist.isNull())
            artist = "";
        artist = NConvert_n::fromUTF8PercentEncoding(artist);
    }
    QString genre;
    if(session.url().hasQueryItem("genre"))// Cos of NULL test
    {
        genre = session.url().queryItemValue("genre");
        if (genre.isNull())
            genre = "";
        genre = NConvert_n::fromUTF8PercentEncoding(genre);
    }

    int year = session.url().queryItemValue("year").toInt(&ok);
    if (!ok)
        year = -1;

    const NTcpServerAuthSession authSession = getAuthServices().getSession(session.sessionId());
    logMessage(session.socket()->peerAddress().toString(),
          QString("%1 is looking for album: \"%2\"; start: %3; limit: %4, dir:\"%5\"").
          arg(authSession.login()).arg(NConvert_n::fromUTF8PercentEncoding(search)).arg(start).arg(limit).arg(dir));

    int totalCount = NMDB.getAlbumListCount(searches, year, genre, artist);
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();
    QScriptValue svData = se.newArray(totalCount);
    svRoot.setProperty(RSP_DATA, svData);
    // TODO: manage limit = -1 to get all album
    bool succeed = NMDB.getAlbumList(se, svData, totalCount, searches, start,
                                         limit, dir, year, genre, artist);
    setJsonRootReponse(svRoot, totalCount, succeed);
    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
예제 #11
0
void GeoHelper::searchFinishedSlot(QGeoSearchReply *reply)
{
    if (reply->error() == QGeoSearchReply::NoError)
    {
        QScriptEngine scriptEngine;
        QScriptValue replyObject = scriptEngine.newArray();

        QList<QGeoPlace> places = reply->places();
        for (int i = 0; i < places.count(); i++)
        {
            QScriptValue placeObject = scriptEngine.newObject();

            QScriptValue coordinateObject = scriptEngine.newObject();
            QGeoCoordinate coordinate = places[i].coordinate();
            coordinateObject.setProperty("latitude", QScriptValue(coordinate.latitude()));
            coordinateObject.setProperty("longitude", QScriptValue(coordinate.longitude()));
            placeObject.setProperty("coordinate", coordinateObject);

            QScriptValue addressObject = scriptEngine.newObject();
            QGeoAddress address = places[i].address();

            if (!address.isEmpty())
            {
                addressObject.setProperty("country", address.country());
                addressObject.setProperty("countryCode", address.countryCode());
                addressObject.setProperty("state", address.state());
                addressObject.setProperty("county", address.county());
                addressObject.setProperty("city", address.city());
                addressObject.setProperty("district", address.district());
                addressObject.setProperty("street", address.street());
                addressObject.setProperty("postcode", address.postcode());

            }

            placeObject.setProperty("address", addressObject);
            replyObject.setProperty(i, placeObject);
        }


        QScriptValue fun = scriptEngine.evaluate("(function(a) { return JSON.stringify(a); })");
        QScriptValueList args;
        args << replyObject;
        QScriptValue result = fun.call(QScriptValue(), args);

        emit searchReply(result.toString());
    }


}
예제 #12
0
QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
{
    QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);

    if (type == qMetaTypeId<QScriptValue>()) {
        return QScriptDeclarativeClass::Value(engine, *qscriptValuePtr);
    } else if (type == QMetaType::Int) {
        return QScriptDeclarativeClass::Value(engine, int(intValue));
    } else if (type == QMetaType::UInt) {
        return QScriptDeclarativeClass::Value(engine, uint(intValue));
    } else if (type == QMetaType::Bool) {
        return QScriptDeclarativeClass::Value(engine, boolValue);
    } else if (type == QMetaType::Double) {
        return QScriptDeclarativeClass::Value(engine, doubleValue);
    } else if (type == QMetaType::Float) {
        return QScriptDeclarativeClass::Value(engine, floatValue);
    } else if (type == QMetaType::QString) {
        return QScriptDeclarativeClass::Value(engine, *qstringPtr);
    } else if (type == QMetaType::QObjectStar) {
        if (qobjectPtr)
            QDeclarativeData::get(qobjectPtr, true)->setImplicitDestructible();
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(qobjectPtr));
    } else if (type == qMetaTypeId<QList<QObject *> >()) {
        QList<QObject *> &list = *qlistPtr;
        QScriptValue rv = engine->newArray(list.count());
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        for (int ii = 0; ii < list.count(); ++ii) {
            QObject *object = list.at(ii);
            QDeclarativeData::get(object, true)->setImplicitDestructible();
            rv.setProperty(ii, priv->objectClass->newQObject(object));
        }
        return QScriptDeclarativeClass::Value(engine, rv);
    } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
        QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e);
        QScriptValue rv = ep->scriptValueFromVariant(*qvariantPtr);
        if (rv.isQObject()) {
            QObject *object = rv.toQObject();
            if (object)
                QDeclarativeData::get(object, true)->setImplicitDestructible();
        }
        return QScriptDeclarativeClass::Value(engine, rv);
    } else {
        return QScriptDeclarativeClass::Value();
    }
}
예제 #13
0
void tst_QScriptClass::newInstance()
{
    QScriptEngine eng;

    TestClass cls(&eng);

    QScriptValue obj1 = eng.newObject(&cls);
    QVERIFY(!obj1.data().isValid());
    QVERIFY(obj1.prototype().strictlyEquals(cls.prototype()));
    QEXPECT_FAIL("", "classname is not implemented", Continue);
    QCOMPARE(obj1.toString(), QString::fromLatin1("[object TestClass]"));
    QCOMPARE(obj1.scriptClass(), (QScriptClass*)&cls);

    QScriptValue num(&eng, 456);
    QScriptValue obj2 = eng.newObject(&cls, num);
    QVERIFY(obj2.data().strictlyEquals(num));
    QVERIFY(obj2.prototype().strictlyEquals(cls.prototype()));
    QCOMPARE(obj2.scriptClass(), (QScriptClass*)&cls);

    QScriptValue obj3 = eng.newObject();
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)0);
    obj3.setScriptClass(&cls);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls);

    obj3.setScriptClass(0);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)0);
    obj3.setScriptClass(&cls);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls);

    TestClass cls2(&eng);
    obj3.setScriptClass(&cls2);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls2);

    // undefined behavior really, but shouldn't crash
    QScriptValue arr = eng.newArray();
    QVERIFY(arr.isArray());
    QCOMPARE(arr.scriptClass(), (QScriptClass*)0);
    QTest::ignoreMessage(QtWarningMsg, "QScriptValue::setScriptClass() failed: cannot change class of non-QScriptObject");
    arr.setScriptClass(&cls);
    QEXPECT_FAIL("", "Changing class of arbitrary script object is not allowed (it's OK)", Continue);
    QCOMPARE(arr.scriptClass(), (QScriptClass*)&cls);
    QEXPECT_FAIL("", "Changing class of arbitrary script object is not allowed (it's OK)", Continue);
    QVERIFY(!arr.isArray());
    QVERIFY(arr.isObject());
}
예제 #14
0
void tst_QScriptClass::newInstance()
{
    QScriptEngine eng;

    TestClass cls(&eng);

    QScriptValue obj1 = eng.newObject(&cls);
    QVERIFY(!obj1.data().isValid());
    QVERIFY(obj1.prototype().strictlyEquals(cls.prototype()));
    QCOMPARE(obj1.toString(), QString::fromLatin1("[object TestClass]"));
    QCOMPARE(obj1.scriptClass(), (QScriptClass*)&cls);

    QScriptValue num(&eng, 456);
    QScriptValue obj2 = eng.newObject(&cls, num);
    QVERIFY(obj2.data().strictlyEquals(num));
    QVERIFY(obj2.prototype().strictlyEquals(cls.prototype()));
    QCOMPARE(obj2.scriptClass(), (QScriptClass*)&cls);

    QScriptValue obj3 = eng.newObject();
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)0);
    obj3.setScriptClass(&cls);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls);

    obj3.setScriptClass(0);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)0);
    obj3.setScriptClass(&cls);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls);

    TestClass cls2(&eng);
    obj3.setScriptClass(&cls2);
    QCOMPARE(obj3.scriptClass(), (QScriptClass*)&cls2);

    // undefined behavior really, but shouldn't crash
    QScriptValue arr = eng.newArray();
    QVERIFY(arr.isArray());
    QCOMPARE(arr.scriptClass(), (QScriptClass*)0);
    arr.setScriptClass(&cls);
    QCOMPARE(arr.scriptClass(), (QScriptClass*)&cls);
    QVERIFY(!arr.isArray());
    QVERIFY(arr.isObject());
}
예제 #15
0
QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e)
{
    QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(e);

    if (type == qMetaTypeId<QScriptValue>()) {
        return QScriptDeclarativeClass::Value(engine, *((QScriptValue *)&data));
    } else if (type == QMetaType::Int) {
        return QScriptDeclarativeClass::Value(engine, *((int *)&data));
    } else if (type == QMetaType::UInt) {
        return QScriptDeclarativeClass::Value(engine, *((uint *)&data));
    } else if (type == QMetaType::Bool) {
        return QScriptDeclarativeClass::Value(engine, *((bool *)&data));
    } else if (type == QMetaType::Double) {
        return QScriptDeclarativeClass::Value(engine, *((double *)&data));
    } else if (type == QMetaType::Float) {
        return QScriptDeclarativeClass::Value(engine, *((float *)&data));
    } else if (type == QMetaType::QString) {
        return QScriptDeclarativeClass::Value(engine, *((QString *)&data));
    } else if (type == QMetaType::QObjectStar) {
        QObject *object = *((QObject **)&data);
        QDeclarativeData::get(object, true)->setImplicitDestructible();
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        return QScriptDeclarativeClass::Value(engine, priv->objectClass->newQObject(object));
    } else if (type == qMetaTypeId<QList<QObject *> >()) {
        QList<QObject *> &list = *(QList<QObject *>*)&data;
        QScriptValue rv = engine->newArray(list.count());
        QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(e);
        for (int ii = 0; ii < list.count(); ++ii) {
            QObject *object = list.at(ii);
            QDeclarativeData::get(object, true)->setImplicitDestructible();
            rv.setProperty(ii, priv->objectClass->newQObject(object));
        }
        return QScriptDeclarativeClass::Value(engine, rv);
    } else if (type == -1 || type == qMetaTypeId<QVariant>()) {
        return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data)));
    } else {
        return QScriptDeclarativeClass::Value();
    }
}
NResponse & NTcpServerSocketCfgServices::getAvailableLevelList(NResponse & response)
{
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();

    QStringList levels  = NTcpServerAuthSession::toStringLevel(AUTH_LEVEL_ADMIN, " ").split(" ");

    svRoot.setProperty(RSP_SUCCESS , QScriptValue(levels.count() > 0));
    svRoot.setProperty(RSP_MSG, QScriptValue(levels.count() > 0 ? RSP_MSG_LOADED : RSP_MSG_NO_RESULTS));
    svRoot.setProperty(RSP_COUNT, QScriptValue(levels.count()));

    QScriptValue svData = se.newArray(levels.count());
    svRoot.setProperty(RSP_DATA, svData);
    for(int i = 0; i < levels.count(); i++)
    {
        QScriptValue svLevel = se.newObject();
        svData.setProperty(i, svLevel);
        svLevel.setProperty("id", NTcpServerAuthSession::toIntLevel(levels.at(i)));
        svLevel.setProperty("level", levels.at(i));
    }
    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
예제 #17
0
void GeoHelper::routingFinishedSlot(QGeoRouteReply * reply)
{

    if (reply->error() == QGeoRouteReply::NoError)
    {
        QScriptEngine scriptEngine;
        QScriptValue replyObject = scriptEngine.newArray();

        QList<QGeoCoordinate> waypoints = reply->request().waypoints();
        double lat1 = 0;
        double lon1 = 0;
        double lat2 = 0;
        double lon2 = 0;

        if (waypoints.count() > 0)
        {
            /*
            QString msg = QString("lat %1, lon %2 => lat %3, lon %4").
                    arg(waypoints.at(0).latitude()).arg(waypoints.at(0).longitude()).
                    arg(waypoints.at((waypoints.count()-1)).latitude()).arg(waypoints.at((waypoints.count()-1)).longitude());
            emit routingError(msg);
            */
            lat1 = waypoints.at(0).latitude();
            lon1 = waypoints.at(0).longitude();
            lat2 = waypoints.at((waypoints.count()-1)).latitude();
            lon2 = waypoints.at((waypoints.count()-1)).longitude();

        }


        for (int i = 0; i < reply->routes().size(); ++i)
        {
            QScriptValue routeObject = scriptEngine.newObject();
            QGeoRoute route = reply->routes().at(i);

            routeObject.setProperty("distance", QScriptValue(route.distance()));
            routeObject.setProperty("travelTime", QScriptValue(route.travelTime()));
            routeObject.setProperty("lat1", QScriptValue(lat1));
            routeObject.setProperty("lon1", QScriptValue(lon1));
            routeObject.setProperty("lat2", QScriptValue(lat2));
            routeObject.setProperty("lon2", QScriptValue(lon2));


            QScriptValue pathObject = scriptEngine.newArray();
            QList<QGeoCoordinate> path = route.path();
            for (int p = 0; p < path.length(); p++)
            {
                QScriptValue coordinateObject = scriptEngine.newObject();
                coordinateObject.setProperty("latitude", QScriptValue(path[p].latitude()));
                coordinateObject.setProperty("longitude", QScriptValue(path[p].longitude()));
                pathObject.setProperty(p, coordinateObject);

            }

            routeObject.setProperty("path", pathObject);

            replyObject.setProperty(i, routeObject);

        }

        QScriptValue fun = scriptEngine.evaluate("(function(a) { return JSON.stringify(a); })");
        QScriptValueList args;
        args << replyObject;
        QScriptValue result = fun.call(QScriptValue(), args);

        emit routingReply(result.toString());

    }
}
NResponse & NTcpServerSocketMusicServices::getTitle(const NClientSession & session,
                                                       NResponse & response)
{
    bool ok;
    int start = session.url().queryItemValue("start").toInt();
    if (!ok)
        start = 0;
    int limit  = session.url().queryItemValue("limit").toInt(&ok);
    if (!ok)
        limit = 25;
    QString dir = session.url().queryItemValue("dir");
    QString sort = session.url().queryItemValue("sort");
    QString search = session.url().queryItemValue("search");
    QStringList searches = search.split("+", QString::SkipEmptyParts);
    searches = NConvert_n::fromUTF8PercentEncoding(searches);

    QString album;
    if(session.url().hasQueryItem("album")) // Cos of NULL test
    {
        album = session.url().queryItemValue("album");
        if (album.isNull())
            album = "";
        album = NConvert_n::fromUTF8PercentEncoding(album);

    }
    QString artist;
    if(session.url().hasQueryItem("artist"))// Cos of NULL test
    {
        artist = session.url().queryItemValue("artist");
        if (artist.isNull())
            artist = "";
        artist = NConvert_n::fromUTF8PercentEncoding(artist);
    }
    QString genre;
    if(session.url().hasQueryItem("genre"))// Cos of NULL test
    {	genre = session.url().queryItemValue("genre");
        if (genre.isNull())
            genre = "";
        genre = NConvert_n::fromUTF8PercentEncoding(genre);
    }

    int year  = session.url().queryItemValue("year").toInt(&ok);
    if (!ok)
        year = -1;

    const NTcpServerAuthSession authSession = getAuthServices().getSession(session.sessionId());
    logMessage(session.socket()->peerAddress().toString(),
          QString("%1 is looking for music search:\"%2\"; album:\"%3\"; artist:\"%4\";"\
             "genre:\"%5\"; year:\"%6\"; start:\"%7\"; "\
             "limit:\"%8\"; sort:\"%9\"; dir:\"%10\"").
          arg(authSession.login()). // 1
          arg(NConvert_n::fromUTF8PercentEncoding(search)).// 2
          arg(album).// 3
          arg(artist).// 4
          arg(genre).// 5
          arg(year).// 6
          arg(start).// 7
          arg(limit).// 8
          arg(sort).// 9
          arg(dir));// 10

    int totalCount = NMDB.getTitleListCount(searches, album, artist, genre, year);
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();
    QScriptValue svData = se.newArray(totalCount);
    svRoot.setProperty(RSP_DATA, svData);

    bool succeed = NMDB.getTitleList(se, svData, searches, album, artist, genre, year,
                                         start, limit, sort, dir);

    setJsonRootReponse(svRoot, totalCount, succeed);

    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
NResponse & NTcpServerSocketUserServices::postUser(const NClientSession & session, NResponse & response)
{
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();

    se.evaluate("var data = " + QString::fromUtf8(session.content()));
    if (se.hasUncaughtException()){
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_JSON));
        logDebug("NTcpServerSocketUserServices::svcPostUser", se.uncaughtExceptionBacktrace());
        logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    QScriptValue svReadUser = se.globalObject().property("data").property("data");
    QString email = svReadUser.property("email").toString();
    QString name = svReadUser.property("name").toString();
    QString password = getConfig().toPasswordHash(svReadUser.property("password").toString());
    QString preferences = svReadUser.property("preferences").toString();
    QString enabled = svReadUser.property("enabled").toString();
    QString level = NTcpServerAuthSession::normalizeLevels(svReadUser.property("level").toString());

    logDebug("email", email);
    logDebug("name", name);
    logDebug("password", password);
    logDebug("preferences", preferences);
    logDebug("enabled", enabled);
    logDebug("level", level);

    // User already exists?
    NStringMap user = NDB.getUserByEmail(email);

    if (user.count() > 0) // User already exists
    {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, "User already exists");
        logMessage("Registration failed", QString("already registered; %1(%2); user agent: %3").
              arg(email).
              arg(session.peerAddress()).
              arg(session.userAgent()));

        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    // User do not exists
    int userId = NDB.addUser(name, email, password, level, preferences, QVariant(enabled).toBool());
    if (userId < 0) // Error
    {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        QString errorMsg;
        switch(userId){
        case DB_USER_ERROR_INVALID_PARAMS:
            errorMsg = "Invalid params";
            break;
        case  DB_USER_ERROR_QUERY:
            errorMsg = "Query error";
            break;
        }
        svRoot.setProperty(RSP_MSG, errorMsg);
        logMessage("User add failed", QString("%1; %2(%3); user agent: %4").
              arg(errorMsg).
              arg(email).
              arg(session.peerAddress()).
              arg(session.userAgent()));

        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    svRoot.setProperty(RSP_SUCCESS , QScriptValue(true));
    svRoot.setProperty(RSP_MSG, QString("User %1 added").arg(email));
    logMessage("User add succeed", QString("%1, %2(%3); user agent: %4").
               arg(userId).
               arg(email).
               arg(session.peerAddress()).
               arg(session.userAgent()));

    // We add new user to response
    QScriptValue svData = se.newArray(1);
    svRoot.setProperty(RSP_DATA, svData);
    QScriptValue svUser = se.newObject();
    svData.setProperty(0, svUser);
    svUser.setProperty("id", userId);
    svUser.setProperty("name", name);
    svUser.setProperty("email", email);
    svUser.setProperty("preferences", preferences);
    svUser.setProperty("enabled", QVariant(enabled).toBool());
    svUser.setProperty("level", level);

    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
NResponse & NTcpServerSocketUserServices::putUser(const NClientSession & session, NResponse & response)
{
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();

    QString strId = session.resource();
    logDebug("svcPutUser strId", strId);
    bool ok;
    int id = strId.toInt(&ok);
    if (!ok)
    {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_USER));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    se.evaluate("var data = " + QString::fromUtf8(session.content()));
    if (se.hasUncaughtException()){
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_JSON));
        logDebug("NTcpServerSocketUserServices::svcPutUser", se.uncaughtExceptionBacktrace());
        logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    NStringMap user = NDB.getUserById(id);
    if (user.count()  == 0)
    {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_USER));
        //logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    QScriptValue svReadUser = se.globalObject().property("data").property("data");
    QString email = svReadUser.property("email").toString();
    QString password = getConfig().toPasswordHash(svReadUser.property("password").toString());
    QString name = svReadUser.property("name").toString();
    QString preferences = svReadUser.property("preferences").toString();
    QString enabled = svReadUser.property("enabled").toString();
    QString level = NTcpServerAuthSession::normalizeLevels(svReadUser.property("level").toString());

    email = email.isEmpty() ? user["email"] : email;
    password = password.isEmpty() ? user["password"] : password;
    name = name.isEmpty() ? user["name"] : name;
    preferences = preferences.isEmpty() ? user["preferences"] : preferences;
    enabled = enabled.isEmpty() ? user["enabled"] : enabled;
    level = level.isEmpty() ? user["level"] : level;

    logDebug("email", email);
    logDebug("password", password);
    logDebug("name", name);
    logDebug("preferences", preferences);
    logDebug("enabled", enabled);
    logDebug("level", level);

    if (!NDB.updateUser(id, email, password, name, preferences,
                        QVariant(enabled).toBool(),level)) {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_ERROR_OCCURRED));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    logMessage("User update succeed", QString("%1, %2 (%3); user agent: %4").
               arg(id).
               arg(email).
               arg(session.peerAddress()).
               arg(session.userAgent()));

    svRoot.setProperty(RSP_SUCCESS , QScriptValue(true));
    svRoot.setProperty(RSP_MSG, QScriptValue(QString(RSP_MSG_N_UPDATED).arg(id)));
    QScriptValue svData = se.newArray();
    svRoot.setProperty(RSP_DATA, svData);
    QScriptValue svUser = se.newObject();
    svData.setProperty(0, svUser);
    svUser.setProperty("id", id);
    svUser.setProperty("email", email);
    svUser.setProperty("name", name);
    svUser.setProperty("preferences", preferences);
    svUser.setProperty("enabled", QVariant(enabled).toBool());
    svUser.setProperty("level", level);

    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
NResponse & NTcpServerSocketCfgServices::putSharedDir(const NClientSession & session, NResponse & response)
{
    //logDebug("NTcpServerSocketCfgServices::svcPutSharedDir", session.postData());
    QScriptEngine se;
    QScriptValue svRoot = se.newObject();

    QString strId = session.resource();
    logDebug("svcPutSharedDir strId", strId);
    bool ok;
    int id = strId.toInt(&ok);
    if (!ok)
    {
        svRoot.setProperty(RSP_SUCCESS, QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_INDEX_PROPERTY));
        //logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    se.evaluate("var data = " + QString::fromUtf8(session.content()));
    if (se.hasUncaughtException()){
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_JSON));
        logDebug("NTcpServerSocketCfgServices::svcPutSharedDir", se.uncaughtExceptionBacktrace());
        logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    NDirList sharedDirs = getConfig().sharedDirectories();
    if (id >= sharedDirs.count())
    {
        svRoot.setProperty(RSP_SUCCESS , QScriptValue(false));
        svRoot.setProperty(RSP_MSG, QScriptValue(RSP_MSG_INVALID_INDEX));
        //logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
        response.setData(NJson::serializeToQByteArray(svRoot));
        return response;
    }

    QScriptValue svReadDir = se.globalObject().property("data").property("data");
    QString path = svReadDir.property("path").toString();
    QString recursive = svReadDir.property("recursive").toString();
    QString shared = svReadDir.property("shared").toString();

    logDebug("path", path);
    logDebug("recursive", recursive);
    logDebug("shared", shared);

    NDir dir = sharedDirs.at(id);
    NDir modifiedDir = NDir(path.isEmpty() ? dir.path() : path,
                            recursive.isEmpty() ? dir.recursive() : QVariant(recursive).toBool(),
                            shared.isEmpty() ? dir.shared() : QVariant(shared).toBool());

    modifiedDir = getConfig().modifySharedDirectory(id, modifiedDir);
    svRoot.setProperty(RSP_SUCCESS , QScriptValue(true));
    svRoot.setProperty(RSP_MSG, QScriptValue(QString(RSP_MSG_N_UPDATED).arg(id)));
    QScriptValue svData = se.newArray();
    svRoot.setProperty(RSP_DATA, svData);
    QScriptValue svDir = se.newObject();
    svData.setProperty(0, svDir);
    svDir.setProperty("id", id);
    svDir.setProperty("path", modifiedDir.path());
    svDir.setProperty("recursive", modifiedDir.recursive());
    svDir.setProperty("shared", modifiedDir.shared());
    svDir.setProperty("exists", modifiedDir.exists());
    //logDebug("NJson::serialize(svRoot)", NJson::serialize(svRoot));
    response.setData(NJson::serializeToQByteArray(svRoot));
    return response;
}
예제 #22
0
void tst_QScriptValueIterator::iterateArray()
{
    QFETCH(QStringList, propertyNames);
    QFETCH(QStringList, propertyValues);

    QScriptEngine engine;
    QScriptValue array = engine.newArray();

    // Fill the array
    for (int i = 0; i < propertyNames.size(); ++i) {
        array.setProperty(propertyNames.at(i), propertyValues.at(i));
    }

    // Iterate thru array properties. Note that the QScriptValueIterator doesn't guarantee
    // any order on the iteration!
    int length = array.property("length").toInt32();
    QCOMPARE(length, propertyNames.size());

    bool iteratedThruLength = false;
    QHash<QString, QScriptValue> arrayProperties;
    QScriptValueIterator it(array);

    // Iterate forward
    while (it.hasNext()) {
        it.next();

        const QString name = it.name();
        if (name == QString::fromLatin1("length")) {
            QVERIFY(it.value().isNumber());
            QCOMPARE(it.value().toInt32(), length);
            QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
            QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
            iteratedThruLength = true;
            continue;
        }

        // Storing the properties we iterate in a hash to compare with test data.
        QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
        arrayProperties.insert(name, it.value());
        QCOMPARE(it.flags(), array.propertyFlags(name));
        QVERIFY(it.value().strictlyEquals(array.property(name)));
    }

    // Verify properties
    QVERIFY(iteratedThruLength);
    QCOMPARE(arrayProperties.size(), propertyNames.size());
    for (int i = 0; i < propertyNames.size(); ++i) {
        QVERIFY(arrayProperties.contains(propertyNames.at(i)));
        QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
    }

    // Iterate backwards
    arrayProperties.clear();
    iteratedThruLength = false;
    it.toBack();

    while (it.hasPrevious()) {
        it.previous();

        const QString name = it.name();
        if (name == QString::fromLatin1("length")) {
            QVERIFY(it.value().isNumber());
            QCOMPARE(it.value().toInt32(), length);
            QCOMPARE(it.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
            QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
            iteratedThruLength = true;
            continue;
        }

        // Storing the properties we iterate in a hash to compare with test data.
        QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
        arrayProperties.insert(name, it.value());
        QCOMPARE(it.flags(), array.propertyFlags(name));
        QVERIFY(it.value().strictlyEquals(array.property(name)));
    }

    // Verify properties
    QVERIFY(iteratedThruLength);
    QCOMPARE(arrayProperties.size(), propertyNames.size());
    for (int i = 0; i < propertyNames.size(); ++i) {
        QVERIFY(arrayProperties.contains(propertyNames.at(i)));
        QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
    }

    // ### Do we still need this test?
    // Forward test again but as object
    arrayProperties.clear();
    iteratedThruLength = false;
    QScriptValue arrayObject = engine.toObject(array);
    QScriptValueIterator it2(arrayObject);

    while (it2.hasNext()) {
        it2.next();

        const QString name = it2.name();
        if (name == QString::fromLatin1("length")) {
            QVERIFY(it2.value().isNumber());
            QCOMPARE(it2.value().toInt32(), length);
            QCOMPARE(it2.flags(), QScriptValue::SkipInEnumeration | QScriptValue::Undeletable);
            QVERIFY2(!iteratedThruLength, "'length' appeared more than once during iteration.");
            iteratedThruLength = true;
            continue;
        }

        // Storing the properties we iterate in a hash to compare with test data.
        QVERIFY2(!arrayProperties.contains(name), "property appeared more than once during iteration.");
        arrayProperties.insert(name, it2.value());
        QCOMPARE(it2.flags(), arrayObject.propertyFlags(name));
        QVERIFY(it2.value().strictlyEquals(arrayObject.property(name)));
    }

    // Verify properties
    QVERIFY(iteratedThruLength);
    QCOMPARE(arrayProperties.size(), propertyNames.size());
    for (int i = 0; i < propertyNames.size(); ++i) {
        QVERIFY(arrayProperties.contains(propertyNames.at(i)));
        QCOMPARE(arrayProperties.value(propertyNames.at(i)).toString(), propertyValues.at(i));
    }
}
예제 #23
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;
}