Showing the changes to libraries/script-engine/src/ScriptEngine.cpp (1 of 4 files). Show all
Unified · Split
| @@ -2476,7 +2476,7 @@ void ScriptEngine::callWithEnvironment(const EntityItemID& entityID, const QUrl& · 2475 unmodified lines | ||
| 2476 | 2476 | doWithEnvironment(entityID, sandboxURL, operation); |
| 2477 | 2477 | } |
| 2478 | 2478 | |
| 2479 | −void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params) { | |
| 2479 | +void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QString& methodName, const QStringList& params, const QUuid& remoteCallerID) { | |
| 2480 | 2480 | if (QThread::currentThread() != thread()) { |
| 2481 | 2481 | #ifdef THREAD_DEBUGGING |
| 2482 | 2482 | qCDebug(scriptengine) << "*** WARNING *** ScriptEngine::callEntityScriptMethod() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] " |
| @@ -2486,7 +2486,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 3 unmodified lines | ||
| 2486 | 2486 | QMetaObject::invokeMethod(this, "callEntityScriptMethod", |
| 2487 | 2487 | Q_ARG(const EntityItemID&, entityID), |
| 2488 | 2488 | Q_ARG(const QString&, methodName), |
| 2489 | − Q_ARG(const QStringList&, params)); | |
| 2489 | + Q_ARG(const QStringList&, params), | |
| 2490 | + Q_ARG(const QUuid&, remoteCallerID)); | |
| 2490 | 2491 | return; |
| 2491 | 2492 | } |
| 2492 | 2493 | #ifdef THREAD_DEBUGGING |
| @@ -2500,13 +2501,41 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS · 7 unmodified lines | ||
| 2500 | 2501 | if (isEntityScriptRunning(entityID)) { |
| 2501 | 2502 | EntityScriptDetails details = _entityScripts[entityID]; |
| 2502 | 2503 | QScriptValue entityScript = details.scriptObject; // previously loaded |
| 2503 | − if (entityScript.property(methodName).isFunction()) { | |
| 2504 | + | |
| 2505 | + // If this is a remote call, we need to check to see if the function is remotely callable | |
| 2506 | + // we do this by checking for the existance of the 'remotelyCallable' property on the | |
| 2507 | + // entityScript. And we confirm that the method name is included. If this fails, the | |
| 2508 | + // function will not be called. | |
| 2509 | + bool callAllowed = false; | |
| 2510 | + if (remoteCallerID == QUuid()) { | |
| 2511 | + callAllowed = true; | |
| 2512 | + } else { | |
| 2513 | + if (entityScript.property("remotelyCallable").isArray()) { | |
| 2514 | + auto callables = entityScript.property("remotelyCallable"); | |
| 2515 | + auto callableCount = callables.property("length").toInteger(); | |
| 2516 | + for (int i = 0; i < callableCount; i++) { | |
| 2517 | + auto callable = callables.property(i).toString(); | |
| 2518 | + if (callable == methodName) { | |
| 2519 | + callAllowed = true; | |
| 2520 | + break; | |
| 2521 | + } | |
| 2522 | + } | |
| 2523 | + } | |
| 2524 | + if (!callAllowed) { | |
| 2525 | + qDebug() << "Method [" << methodName << "] not remotely callable."; | |
| 2526 | + } | |
| 2527 | + } | |
| 2528 | + | |
| 2529 | + if (callAllowed && entityScript.property(methodName).isFunction()) { | |
| 2504 | 2530 | QScriptValueList args; |
| 2505 | 2531 | args << entityID.toScriptValue(this); |
| 2506 | 2532 | args << qScriptValueFromSequence(this, params); |
| 2533 | + | |
| 2534 | + QScriptValue oldData = this->globalObject().property("remoteCallerID"); | |
| 2535 | + this->globalObject().setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global. | |
| 2507 | 2536 | callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args); |
| 2537 | + this->globalObject().setProperty("remoteCallerID", oldData); | |
| 2508 | 2538 | } |
| 2509 | − | |
| 2510 | 2539 | } |
| 2511 | 2540 | } |
| 2512 | 2541 | |