示例#1
0
void EntityScriptServer::run() {
    DependencyManager::set<ScriptEngines>(ScriptEngine::ENTITY_SERVER_SCRIPT);
    DependencyManager::set<EntityScriptServerServices>();

    // make sure we request our script once the agent connects to the domain
    auto nodeList = DependencyManager::get<NodeList>();

    ThreadedAssignment::commonInit(ENTITY_SCRIPT_SERVER_LOGGING_NAME, NodeType::EntityScriptServer);

    // Setup MessagesClient
    auto messagesClient = DependencyManager::set<MessagesClient>();
    messagesClient->startThread();

    DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
    connect(&domainHandler, &DomainHandler::settingsReceived, this, &EntityScriptServer::handleSettings);

    // make sure we hear about connected nodes so we can grab an ATP script if a request is pending
    connect(nodeList.data(), &LimitedNodeList::nodeActivated, this, &EntityScriptServer::nodeActivated);
    connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &EntityScriptServer::nodeKilled);

    nodeList->addSetOfNodeTypesToNodeInterestSet({
        NodeType::Agent, NodeType::AudioMixer, NodeType::AvatarMixer,
        NodeType::EntityServer, NodeType::MessagesMixer, NodeType::AssetServer
    });

    // Setup Script Engine
    resetEntitiesScriptEngine();

    auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
    entityScriptingInterface->init();

    _entityViewer.init();
    
    // setup the JSON filter that asks for entities with a non-default serverScripts property
    QJsonObject queryJSONParameters;
    queryJSONParameters[EntityJSONQueryProperties::SERVER_SCRIPTS_PROPERTY] = EntityQueryFilterSymbol::NonDefault;

    QJsonObject queryFlags;

    queryFlags[EntityJSONQueryProperties::INCLUDE_ANCESTORS_PROPERTY] = true;
    queryFlags[EntityJSONQueryProperties::INCLUDE_DESCENDANTS_PROPERTY] = true;

    queryJSONParameters[EntityJSONQueryProperties::FLAGS_PROPERTY] = queryFlags;
    
    // setup the JSON parameters so that OctreeQuery does not use a frustum and uses our JSON filter
    _entityViewer.getOctreeQuery().setJSONParameters(queryJSONParameters);

    entityScriptingInterface->setEntityTree(_entityViewer.getTree());

    DependencyManager::set<AssignmentParentFinder>(_entityViewer.getTree());


    auto tree = _entityViewer.getTree().get();
    connect(tree, &EntityTree::deletingEntity, this, &EntityScriptServer::deletingEntity, Qt::QueuedConnection);
    connect(tree, &EntityTree::addingEntity, this, &EntityScriptServer::addingEntity, Qt::QueuedConnection);
    connect(tree, &EntityTree::entityServerScriptChanging, this, &EntityScriptServer::entityServerScriptChanging, Qt::QueuedConnection);
}
示例#2
0
文件: Agent.cpp 项目: rabedik/hifi
void Agent::run() {
    ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);

    auto nodeList = DependencyManager::get<NodeList>();
    nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet()
                                                 << NodeType::AudioMixer
                                                 << NodeType::AvatarMixer
                                                 << NodeType::EntityServer
                                                );

    _pingTimer = new QTimer(this);
    connect(_pingTimer, SIGNAL(timeout()), SLOT(sendPingRequests()));
    _pingTimer->start(PING_INTERVAL);

    // figure out the URL for the script for this agent assignment
    QUrl scriptURL;
    if (_payload.isEmpty())  {
        scriptURL = QUrl(QString("http://%1:%2/assignment/%3")
            .arg(DependencyManager::get<NodeList>()->getDomainHandler().getIP().toString())
            .arg(DOMAIN_SERVER_HTTP_PORT)
            .arg(uuidStringWithoutCurlyBraces(_uuid)));
    } else {
        scriptURL = QUrl(_payload);
    }

    QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
    QNetworkRequest networkRequest = QNetworkRequest(scriptURL);
    networkRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
    QNetworkReply* reply = networkAccessManager.get(networkRequest);

    QNetworkDiskCache* cache = new QNetworkDiskCache();
    QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
    cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
    networkAccessManager.setCache(cache);

    qDebug() << "Downloading script at" << scriptURL.toString();

    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));

    loop.exec();

    QString scriptContents(reply->readAll());
    delete reply;

    qDebug() << "Downloaded script:" << scriptContents;

    // setup an Avatar for the script to use
    ScriptableAvatar scriptedAvatar(&_scriptEngine);
    scriptedAvatar.setForceFaceTrackerConnected(true);

    // call model URL setters with empty URLs so our avatar, if user, will have the default models
    scriptedAvatar.setFaceModelURL(QUrl());
    scriptedAvatar.setSkeletonModelURL(QUrl());

    // give this AvatarData object to the script engine
    _scriptEngine.setAvatarData(&scriptedAvatar, "Avatar");
    
    auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
   
    _scriptEngine.setAvatarHashMap(avatarHashMap.data(), "AvatarList");
    
    auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
    packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
    packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
    packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
    packetReceiver.registerListener(PacketType::AvatarBillboard, avatarHashMap.data(), "processAvatarBillboardPacket");

    // register ourselves to the script engine
    _scriptEngine.registerGlobalObject("Agent", this);

    if (!_payload.isEmpty()) {
        _scriptEngine.setParentURL(_payload);
    }

    _scriptEngine.init(); // must be done before we set up the viewers

    _scriptEngine.registerGlobalObject("SoundCache", DependencyManager::get<SoundCache>().data());

    QScriptValue webSocketServerConstructorValue = _scriptEngine.newFunction(WebSocketServerClass::constructor);
    _scriptEngine.globalObject().setProperty("WebSocketServer", webSocketServerConstructorValue);

    auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();

    _scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer);
    _entityViewer.setJurisdictionListener(entityScriptingInterface->getJurisdictionListener());
    _entityViewer.init();
    entityScriptingInterface->setEntityTree(_entityViewer.getTree());

    _scriptEngine.setScriptContents(scriptContents);
    _scriptEngine.run();
    setFinished(true);
}
示例#3
0
文件: Agent.cpp 项目: ey6es/hifi
void Agent::run() {
    ThreadedAssignment::commonInit(AGENT_LOGGING_NAME, NodeType::Agent);
    
    auto nodeList = DependencyManager::get<NodeList>();
    nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet()
                                                 << NodeType::AudioMixer
                                                 << NodeType::AvatarMixer
                                                 << NodeType::EntityServer
                                                );
    
    // figure out the URL for the script for this agent assignment
    QUrl scriptURL;
    if (_payload.isEmpty())  {
        scriptURL = QUrl(QString("http://%1:%2/assignment/%3")
            .arg(DependencyManager::get<NodeList>()->getDomainHandler().getIP().toString())
            .arg(DOMAIN_SERVER_HTTP_PORT)
            .arg(uuidStringWithoutCurlyBraces(_uuid)));
    } else {
        scriptURL = QUrl(_payload);
    }
   
    QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
    QNetworkReply *reply = networkAccessManager.get(QNetworkRequest(scriptURL));
    
    QNetworkDiskCache* cache = new QNetworkDiskCache();
    QString cachePath = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
    cache->setCacheDirectory(!cachePath.isEmpty() ? cachePath : "agentCache");
    networkAccessManager.setCache(cache);
    
    qDebug() << "Downloading script at" << scriptURL.toString();
    
    QEventLoop loop;
    QObject::connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
    
    loop.exec();
    
    QString scriptContents(reply->readAll());
    delete reply;
    
    qDebug() << "Downloaded script:" << scriptContents;
    
    // setup an Avatar for the script to use
    ScriptableAvatar scriptedAvatar(&_scriptEngine);
    scriptedAvatar.setForceFaceshiftConnected(true);

    // call model URL setters with empty URLs so our avatar, if user, will have the default models
    scriptedAvatar.setFaceModelURL(QUrl());
    scriptedAvatar.setSkeletonModelURL(QUrl());
    
    // give this AvatarData object to the script engine
    _scriptEngine.setAvatarData(&scriptedAvatar, "Avatar");
    _scriptEngine.setAvatarHashMap(&_avatarHashMap, "AvatarList");
    
    // register ourselves to the script engine
    _scriptEngine.registerGlobalObject("Agent", this);

    _scriptEngine.init(); // must be done before we set up the viewers
    
    _scriptEngine.registerGlobalObject("SoundCache", &SoundCache::getInstance());

    _scriptEngine.registerGlobalObject("EntityViewer", &_entityViewer);
    _entityViewer.setJurisdictionListener(_scriptEngine.getEntityScriptingInterface()->getJurisdictionListener());
    _entityViewer.init();
    _scriptEngine.getEntityScriptingInterface()->setEntityTree(_entityViewer.getTree());

    _scriptEngine.setScriptContents(scriptContents);
    _scriptEngine.run();
    setFinished(true);
}
示例#4
0
ATPClientApp::ATPClientApp(int argc, char* argv[]) :
    QCoreApplication(argc, argv)
{
    // parse command-line
    QCommandLineParser parser;
    parser.setApplicationDescription("High Fidelity ATP-Client");

    const QCommandLineOption helpOption = parser.addHelpOption();

    const QCommandLineOption verboseOutput("v", "verbose output");
    parser.addOption(verboseOutput);

    const QCommandLineOption uploadOption("T", "upload local file", "local-file-to-send");
    parser.addOption(uploadOption);

    const QCommandLineOption authOption("u", "set usename and pass", "username:password");
    parser.addOption(authOption);

    const QCommandLineOption outputFilenameOption("o", "output filename", "output-file-name");
    parser.addOption(outputFilenameOption);

    const QCommandLineOption domainAddressOption("d", "domain-server address", "127.0.0.1");
    parser.addOption(domainAddressOption);

    const QCommandLineOption listenPortOption("listenPort", "listen port", QString::number(INVALID_PORT));
    parser.addOption(listenPortOption);

    if (!parser.parse(QCoreApplication::arguments())) {
        qCritical() << parser.errorText() << endl;
        parser.showHelp();
        Q_UNREACHABLE();
    }

    if (parser.isSet(helpOption)) {
        parser.showHelp();
        Q_UNREACHABLE();
    }

    _verbose = parser.isSet(verboseOutput);
    if (!_verbose) {
        QLoggingCategory::setFilterRules("qt.network.ssl.warning=false");

        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtDebugMsg, false);
        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtInfoMsg, false);
        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtWarningMsg, false);

        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtDebugMsg, false);
        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtInfoMsg, false);
        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtWarningMsg, false);
    }

    QStringList posArgs = parser.positionalArguments();
    if (posArgs.size() != 1) {
        qDebug() << "give remote url argument";
        parser.showHelp();
        Q_UNREACHABLE();
    }

    _url = QUrl(posArgs[0]);
    if (_url.scheme() != "atp") {
        qDebug() << "url should start with atp:";
        parser.showHelp();
        Q_UNREACHABLE();
    }

    int domainPort = 40103;
    if (_url.port() != -1) {
        domainPort = _url.port();
    }

    if (parser.isSet(outputFilenameOption)) {
        _localOutputFile = parser.value(outputFilenameOption);
    }

    if (parser.isSet(uploadOption)) {
        _localUploadFile = parser.value(uploadOption);
    }

    if (parser.isSet(authOption)) {
        QStringList pieces = parser.value(authOption).split(":");
        if (pieces.size() != 2) {
            qDebug() << "-u should be followed by username:password";
            parser.showHelp();
            Q_UNREACHABLE();
        }

        _username = pieces[0];
        _password = pieces[1];
        _waitingForLogin = true;
    }

    if (parser.isSet(listenPortOption)) {
        _listenPort = parser.value(listenPortOption).toInt();
    }

    _domainServerAddress = QString("127.0.0.1") + ":" + QString::number(domainPort);
    if (parser.isSet(domainAddressOption)) {
        _domainServerAddress = parser.value(domainAddressOption);
    } else if (!_url.host().isEmpty()) {
        QUrl domainURL;
        domainURL.setScheme("hifi");
        domainURL.setHost(_url.host());
        _domainServerAddress = domainURL.toString();
    }

    DependencyManager::registerInheritance<LimitedNodeList, NodeList>();

    DependencyManager::set<StatTracker>();
    DependencyManager::set<AccountManager>([&]{ return QString(HIGH_FIDELITY_ATP_CLIENT_USER_AGENT); });
    DependencyManager::set<AddressManager>();
    DependencyManager::set<NodeList>(NodeType::Agent, _listenPort);

    auto accountManager = DependencyManager::get<AccountManager>();
    accountManager->setIsAgent(true);
    accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());

    auto nodeList = DependencyManager::get<NodeList>();

    // setup a timer for domain-server check ins
    _domainCheckInTimer = new QTimer(nodeList.data());
    connect(_domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn);
    _domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);

    // start the nodeThread so its event loop is running
    // (must happen after the checkin timer is created with the nodelist as it's parent)
    nodeList->startThread();

    const DomainHandler& domainHandler = nodeList->getDomainHandler();
    connect(&domainHandler, SIGNAL(hostnameChanged(const QString&)), SLOT(domainChanged(const QString&)));
    connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &ATPClientApp::domainConnectionRefused);

    connect(nodeList.data(), &NodeList::nodeAdded, this, &ATPClientApp::nodeAdded);
    connect(nodeList.data(), &NodeList::nodeKilled, this, &ATPClientApp::nodeKilled);
    connect(nodeList.data(), &NodeList::nodeActivated, this, &ATPClientApp::nodeActivated);
    connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &ATPClientApp::notifyPacketVersionMismatch);
    nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
                                                 << NodeType::EntityServer << NodeType::AssetServer << NodeType::MessagesMixer);

    if (_verbose) {
        QString username = accountManager->getAccountInfo().getUsername();
        qDebug() << "cached username is" << username << ", isLoggedIn =" << accountManager->isLoggedIn();
    }

    if (!_username.isEmpty()) {

        connect(accountManager.data(), &AccountManager::newKeypair, this, [&](){
            if (_verbose) {
                qDebug() << "new keypair has been created.";
            }
        });

        connect(accountManager.data(), &AccountManager::loginComplete, this, [&](){
            if (_verbose) {
                qDebug() << "login successful";
            }
            _waitingForLogin = false;
            go();
        });
        connect(accountManager.data(), &AccountManager::loginFailed, this, [&](){
            qDebug() << "login failed.";
            _waitingForLogin = false;
            go();
        });
        accountManager->requestAccessToken(_username, _password);
    }

    auto assetClient = DependencyManager::set<AssetClient>();
    assetClient->init();

    if (_verbose) {
        qDebug() << "domain-server address is" << _domainServerAddress;
    }

    DependencyManager::get<AddressManager>()->handleLookupString(_domainServerAddress, false);

    QTimer* _timeoutTimer = new QTimer(this);
    _timeoutTimer->setSingleShot(true);
    connect(_timeoutTimer, &QTimer::timeout, this, &ATPClientApp::timedOut);
    _timeoutTimer->start(TIMEOUT_MILLISECONDS);
}
示例#5
0
ACClientApp::ACClientApp(int argc, char* argv[]) :
    QCoreApplication(argc, argv)
{
    // parse command-line
    QCommandLineParser parser;
    parser.setApplicationDescription("High Fidelity AC client");

    const QCommandLineOption helpOption = parser.addHelpOption();

    const QCommandLineOption verboseOutput("v", "verbose output");
    parser.addOption(verboseOutput);

    const QCommandLineOption authOption("u", "set usename and pass", "username:password");
    parser.addOption(authOption);

    const QCommandLineOption domainAddressOption("d", "domain-server address", "127.0.0.1");
    parser.addOption(domainAddressOption);

    const QCommandLineOption cacheSTUNOption("s", "cache stun-server response");
    parser.addOption(cacheSTUNOption);

    const QCommandLineOption listenPortOption("listenPort", "listen port", QString::number(INVALID_PORT));
    parser.addOption(listenPortOption);

    if (!parser.parse(QCoreApplication::arguments())) {
        qCritical() << parser.errorText() << endl;
        parser.showHelp();
        Q_UNREACHABLE();
    }

    if (parser.isSet(helpOption)) {
        parser.showHelp();
        Q_UNREACHABLE();
    }

    _verbose = parser.isSet(verboseOutput);
    if (!_verbose) {
        QLoggingCategory::setFilterRules("qt.network.ssl.warning=false");

        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtDebugMsg, false);
        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtInfoMsg, false);
        const_cast<QLoggingCategory*>(&networking())->setEnabled(QtWarningMsg, false);

        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtDebugMsg, false);
        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtInfoMsg, false);
        const_cast<QLoggingCategory*>(&shared())->setEnabled(QtWarningMsg, false);
    }
    

    QString domainServerAddress = "127.0.0.1:40103";
    if (parser.isSet(domainAddressOption)) {
        domainServerAddress = parser.value(domainAddressOption);
    }

    if (_verbose) {
        qDebug() << "domain-server address is" << domainServerAddress;
    }

    int listenPort = INVALID_PORT;
    if (parser.isSet(listenPortOption)) {
        listenPort = parser.value(listenPortOption).toInt();
    }

    if (parser.isSet(authOption)) {
        QStringList pieces = parser.value(authOption).split(":");
        if (pieces.size() != 2) {
            qDebug() << "-u should be followed by username:password";
            parser.showHelp();
            Q_UNREACHABLE();
        }

        _username = pieces[0];
        _password = pieces[1];
    }

    DependencyManager::registerInheritance<LimitedNodeList, NodeList>();

    DependencyManager::set<AccountManager>([&]{ return QString("Mozilla/5.0 (HighFidelityACClient)"); });
    DependencyManager::set<AddressManager>();
    DependencyManager::set<NodeList>(NodeType::Agent, listenPort);

    auto accountManager = DependencyManager::get<AccountManager>();
    accountManager->setIsAgent(true);
    accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());

    auto nodeList = DependencyManager::get<NodeList>();

    // setup a timer for domain-server check ins
    QTimer* domainCheckInTimer = new QTimer(nodeList.data());
    connect(domainCheckInTimer, &QTimer::timeout, nodeList.data(), &NodeList::sendDomainServerCheckIn);
    domainCheckInTimer->start(DOMAIN_SERVER_CHECK_IN_MSECS);

    // start the nodeThread so its event loop is running
    // (must happen after the checkin timer is created with the nodelist as it's parent)
    nodeList->startThread();

    const DomainHandler& domainHandler = nodeList->getDomainHandler();
    connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainChanged(QUrl)));
    connect(&domainHandler, &DomainHandler::domainConnectionRefused, this, &ACClientApp::domainConnectionRefused);

    connect(nodeList.data(), &NodeList::nodeAdded, this, &ACClientApp::nodeAdded);
    connect(nodeList.data(), &NodeList::nodeKilled, this, &ACClientApp::nodeKilled);
    connect(nodeList.data(), &NodeList::nodeActivated, this, &ACClientApp::nodeActivated);
    connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &ACClientApp::notifyPacketVersionMismatch);
    nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
                                                 << NodeType::EntityServer << NodeType::AssetServer << NodeType::MessagesMixer);

    if (_verbose) {
        QString username = accountManager->getAccountInfo().getUsername();
        qDebug() << "cached username is" << username << ", isLoggedIn =" << accountManager->isLoggedIn();
    }

    if (!_username.isEmpty()) {

        connect(accountManager.data(), &AccountManager::newKeypair, this, [&](){
            if (_verbose) {
                qDebug() << "new keypair has been created.";
            }
        });

        connect(accountManager.data(), &AccountManager::loginComplete, this, [&](){
            if (_verbose) {
                qDebug() << "login successful";
            }
        });
        connect(accountManager.data(), &AccountManager::loginFailed, this, [&](){
            qDebug() << "login failed.";
        });
        accountManager->requestAccessToken(_username, _password);
    }

    DependencyManager::get<AddressManager>()->handleLookupString(domainServerAddress, false);

    QTimer* doTimer = new QTimer(this);
    doTimer->setSingleShot(true);
    connect(doTimer, &QTimer::timeout, this, &ACClientApp::timedOut);
    doTimer->start(4000);
}