mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:42:58 +02:00
implement callEntityClientMethod
This commit is contained in:
parent
7793506d0f
commit
1128a98e88
6 changed files with 107 additions and 5 deletions
|
@ -30,6 +30,8 @@
|
||||||
#include <UUID.h>
|
#include <UUID.h>
|
||||||
#include <WebSocketServerClass.h>
|
#include <WebSocketServerClass.h>
|
||||||
|
|
||||||
|
#include <EntityScriptClient.h> // for EntityScriptServerStub
|
||||||
|
|
||||||
#include "EntityScriptServerLogging.h"
|
#include "EntityScriptServerLogging.h"
|
||||||
#include "../entities/AssignmentParentFinder.h"
|
#include "../entities/AssignmentParentFinder.h"
|
||||||
|
|
||||||
|
@ -68,6 +70,9 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
||||||
DependencyManager::set<ScriptCache>();
|
DependencyManager::set<ScriptCache>();
|
||||||
DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
|
DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
|
||||||
|
|
||||||
|
DependencyManager::set<EntityScriptServerStub>();
|
||||||
|
|
||||||
|
|
||||||
// Needed to ensure the creation of the DebugDraw instance on the main thread
|
// Needed to ensure the creation of the DebugDraw instance on the main thread
|
||||||
DebugDraw::getInstance();
|
DebugDraw::getInstance();
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,10 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership
|
||||||
connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged);
|
connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged);
|
||||||
connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged);
|
connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged);
|
||||||
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
|
connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged);
|
||||||
|
|
||||||
|
|
||||||
|
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||||
|
packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket");
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
void EntityScriptingInterface::queueEntityMessage(PacketType packetType,
|
||||||
|
@ -571,6 +575,41 @@ void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& m
|
||||||
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
DependencyManager::get<EntityScriptClient>()->callEntityServerMethod(id, method, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
|
||||||
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
DependencyManager::get<EntityScriptServerStub>()->callEntityClientMethod(clientSessionID, entityID, method, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode) {
|
||||||
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer);
|
||||||
|
|
||||||
|
if (entityScriptServer == senderNode) {
|
||||||
|
auto entityID = QUuid::fromRfc4122(receivedMessage->read(NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
auto method = receivedMessage->readString();
|
||||||
|
|
||||||
|
quint16 paramCount;
|
||||||
|
receivedMessage->readPrimitive(¶mCount);
|
||||||
|
|
||||||
|
QStringList params;
|
||||||
|
for (int param = 0; param < paramCount; param++) {
|
||||||
|
auto paramString = receivedMessage->readString();
|
||||||
|
params << paramString;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||||
|
if (_entitiesScriptEngine) {
|
||||||
|
_entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
||||||
|
|
|
@ -189,12 +189,15 @@ public slots:
|
||||||
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
Q_INVOKABLE void deleteEntity(QUuid entityID);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Call a method on an entity. Allows a script to call a method on an entity's script.
|
* Call a method on an entity in the same context as this function is called. Allows a script
|
||||||
* The method will execute in the entity script engine. If the entity does not have an
|
* to call a method on an entity's script. The method will execute in the entity script engine.
|
||||||
* entity script or the method does not exist, this call will have no effect.
|
* If the entity does not have an entity script or the method does not exist, this call will
|
||||||
* If it is running an entity script (specified by the `script` property)
|
* have no effect. If it is running an entity script (specified by the `script` property)
|
||||||
* and it exposes a property with the specified name `method`, it will be called
|
* and it exposes a property with the specified name `method`, it will be called
|
||||||
* using `params` as the list of arguments.
|
* using `params` as the list of arguments. If this is called within an entity script, the
|
||||||
|
* method will be executed on the client in the entity script engine in which it was called. If
|
||||||
|
* this is called in an entity server script, the method will be executed on the entity server
|
||||||
|
* script engine.
|
||||||
*
|
*
|
||||||
* @function Entities.callEntityMethod
|
* @function Entities.callEntityMethod
|
||||||
* @param {EntityID} entityID The ID of the entity to call the method on.
|
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||||
|
@ -218,6 +221,21 @@ public slots:
|
||||||
*/
|
*/
|
||||||
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Call a client method on an entity on a specific client node. Allows a server entity script to call a
|
||||||
|
* method on an entity's client script for a particular client. The method will execute in the entity script
|
||||||
|
* engine on that single client. If the entity does not have an entity script or the method does not exist, or
|
||||||
|
* the client is not connected to the domain, or you attempt to make this call outside of the entity server
|
||||||
|
* script, this call will have no effect.
|
||||||
|
*
|
||||||
|
* @function Entities.callEntityClientMethod
|
||||||
|
* @param {SessionID} clientSessionID The session ID of the client to call the method on.
|
||||||
|
* @param {EntityID} entityID The ID of the entity to call the method on.
|
||||||
|
* @param {string} method The name of the method to call.
|
||||||
|
* @param {string[]} params The list of parameters to call the specified method with.
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params = QStringList());
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* finds the closest model to the center point, within the radius
|
* finds the closest model to the center point, within the radius
|
||||||
* will return a EntityItemID.isKnownID = false if no models are in the radius
|
* will return a EntityItemID.isKnownID = false if no models are in the radius
|
||||||
|
@ -447,6 +465,10 @@ protected:
|
||||||
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
std::lock_guard<std::recursive_mutex> lock(_entitiesScriptEngineLock);
|
||||||
function(_entitiesScriptEngine);
|
function(_entitiesScriptEngine);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
||||||
bool polyVoxWorker(QUuid entityID, std::function<bool(PolyVoxEntityItem&)> actor);
|
bool polyVoxWorker(QUuid entityID, std::function<bool(PolyVoxEntityItem&)> actor);
|
||||||
|
|
|
@ -92,6 +92,31 @@ void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& m
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptServerStub::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) {
|
||||||
|
qDebug() << __FUNCTION__;
|
||||||
|
|
||||||
|
|
||||||
|
// only valid to call this function if you are the entity script server
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
SharedNodePointer targetClient = nodeList->nodeWithUUID(clientSessionID);
|
||||||
|
|
||||||
|
if (nodeList->getOwnerType() == NodeType::EntityScriptServer && targetClient) {
|
||||||
|
auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true);
|
||||||
|
|
||||||
|
packetList->write(entityID.toRfc4122());
|
||||||
|
|
||||||
|
packetList->writeString(method);
|
||||||
|
|
||||||
|
quint16 paramCount = params.length();
|
||||||
|
packetList->writePrimitive(paramCount);
|
||||||
|
|
||||||
|
foreach(const QString& param, params) {
|
||||||
|
packetList->writeString(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *targetClient);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
|
@ -74,4 +74,11 @@ private:
|
||||||
void forceFailureOfPendingRequests(SharedNodePointer node);
|
void forceFailureOfPendingRequests(SharedNodePointer node);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class EntityScriptServerStub : public QObject, public Dependency {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params);
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2510,6 +2510,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
if (remoteCallerID == QUuid()) {
|
if (remoteCallerID == QUuid()) {
|
||||||
callAllowed = true;
|
callAllowed = true;
|
||||||
} else {
|
} else {
|
||||||
|
qDebug() << __FUNCTION__ << "checking remotelyCallable method: " << methodName << " on entityID:" << entityID;
|
||||||
|
|
||||||
if (entityScript.property("remotelyCallable").isArray()) {
|
if (entityScript.property("remotelyCallable").isArray()) {
|
||||||
auto callables = entityScript.property("remotelyCallable");
|
auto callables = entityScript.property("remotelyCallable");
|
||||||
auto callableCount = callables.property("length").toInteger();
|
auto callableCount = callables.property("length").toInteger();
|
||||||
|
@ -2536,6 +2538,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS
|
||||||
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
|
||||||
this->globalObject().property("Script").setProperty("remoteCallerID", oldData);
|
this->globalObject().property("Script").setProperty("remoteCallerID", oldData);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
qDebug() << "Entity script not running for EntityID: " << entityID << " - Method [" << methodName << "] not callable.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue