コード例 #1
0
ファイル: BaseClient.cpp プロジェクト: erikogenvik/cyphesis
/// \brief Create a new account on the server
///
/// @param name User name of the new account
/// @param password Password of the new account
Root BaseClient::createSystemAccount()
{
    Anonymous player_ent;
    player_ent->setAttr("username", create_session_username());
    player_ent->setAttr("password", compose("%1%2", ::rand(), ::rand()));
    player_ent->setParents(std::list<std::string>(1, "sys"));
    
    Create createAccountOp;
    createAccountOp->setArgs1(player_ent);
    createAccountOp->setSerialno(m_connection.newSerialNo());
    send(createAccountOp);
    if (m_connection.wait() != 0) {
        std::cerr << "ERROR: Failed to log into server: \""
                  << m_connection.errorMessage() << "\""
                  << std::endl << std::flush;
        return Root(0);
    }

    const Root & ent = m_connection.getInfoReply();

    if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
        std::cerr << "ERROR: Logged in, but account has no id" << std::endl
                  << std::flush;
    } else {
        m_playerId = ent->getId();
        // m_playerName = name;
    }

    return ent;
}
コード例 #2
0
ファイル: AtlasStreamClient.cpp プロジェクト: 9cat/cyphesis
int AtlasStreamClient::create(const std::string & type,
                              const std::string & username,
                              const std::string & password)
{
    m_username = username;

    Create c;
    Anonymous account;

    account->setAttr("username", username);
    account->setAttr("password", password);
    account->setParents(std::list<std::string>(1, type));

    c->setArgs1(account);
    c->setSerialno(newSerialNo());

    send(c);

    return waitForLoginResponse();
}
コード例 #3
0
void EntityImporterBase::createEntity(const RootEntity & obj, OpVector & res)
{
    ++mStats.entitiesProcessedCount;
    ++mStats.entitiesCreateCount;
    EventProgress.emit();

    m_state = ENTITY_CREATING;

    assert(mTreeStack.size() > 1);
    std::deque<StackEntry>::reverse_iterator I = mTreeStack.rbegin();
    ++I;
    assert(I != mTreeStack.rend());
    const std::string & loc = I->restored_id;

    RootEntity create_arg = obj.copy();

    create_arg->removeAttrFlag(Atlas::Objects::Entity::CONTAINS_FLAG);
    create_arg->removeAttrFlag(Atlas::Objects::Entity::VELOCITY_FLAG);
    create_arg->removeAttrFlag(Atlas::Objects::ID_FLAG);
    create_arg->setLoc(loc);

    //Remove any attribute which references another entity from the Create op.
    //This is because the attribute will at this time with certainty refer to the wrong or a non-existing entity.
    //The attribute will later on be set through a Set op in sendResolvedEntityReferences().
    auto referenceMapEntryI = mEntitiesWithReferenceAttributes.find(obj->getId());
    if (referenceMapEntryI != mEntitiesWithReferenceAttributes.end()) {
        for (const auto& attributeName : referenceMapEntryI->second) {
            create_arg->removeAttr(attributeName);
        }
    }

    Create create;
    create->setArgs1(create_arg);
    create->setFrom(mAvatarId);
    create->setSerialno(newSerialNumber());

    mCreateEntityMapping.insert(std::make_pair(create->getSerialno(), obj->getId()));

    res.push_back(create);
}
コード例 #4
0
void EntityImporterBase::createEntity(const RootEntity & obj, OpVector & res)
{
    ++mStats.entitiesProcessedCount;
    ++mStats.entitiesCreateCount;
    EventProgress.emit();

    m_state = ENTITY_CREATING;

    assert(mTreeStack.size() > 1);
    auto I = mTreeStack.rbegin();
    ++I;
    assert(I != mTreeStack.rend());
    const std::string & loc = I->restored_id;

    RootEntity create_arg = obj.copy();

    create_arg->removeAttrFlag(Atlas::Objects::Entity::CONTAINS_FLAG);
    create_arg->removeAttrFlag(Atlas::Objects::Entity::VELOCITY_FLAG);
    create_arg->removeAttrFlag(Atlas::Objects::ID_FLAG);
    create_arg->setLoc(loc);

    //Remove any attribute which references another entity from the Create op.
    //This is because the attribute will at this time with certainty refer to the wrong or a non-existing entity.
    //The attribute will later on be set through a Set op in sendResolvedEntityReferences().
    auto referenceMapEntryI = mEntitiesWithReferenceAttributes.find(obj->getId());
    if (referenceMapEntryI != mEntitiesWithReferenceAttributes.end()) {
        std::set<std::string> resolvedAttributes;
        for (const auto& referenceEntry : referenceMapEntryI->second) {
            size_t resolvedEntitiesCount = 0;
            //Check if all the referenced entities perhaps already have been created.
            for (const auto& entityId : referenceEntry.referencedEntities) {
                auto resolvedI = mEntityIdMap.find(entityId);
                if (resolvedI != mEntityIdMap.end()) {
                    resolvedEntitiesCount++;
                }
            }

            //If all entities were resolved, we should resolve the property now.
            if (resolvedEntitiesCount == referenceEntry.referencedEntities.size()) {
                Element element = create_arg->getAttr(referenceEntry.propertyName);
                resolveEntityReferences(element);
                create_arg->setAttr(referenceEntry.propertyName, element);
                resolvedAttributes.insert(referenceEntry.propertyName);
            } else {
                create_arg->removeAttr(referenceEntry.propertyName);
            }
        }
        //Remove those attributes that were resolved
        if (resolvedAttributes.size() == referenceMapEntryI->second.size()) {
            //All attributes were resolved, remove the entry completely.
            mEntitiesWithReferenceAttributes.erase(referenceMapEntryI);
        } else {
            //Only remove those entries that were destroyed.
            std::vector<ReferencedEntry> copy;
            for (auto& referenceEntry : referenceMapEntryI->second) {
                if (resolvedAttributes.find(referenceEntry.propertyName) == resolvedAttributes.end()) {
                    copy.push_back(std::move(referenceEntry));
                }
            }
            referenceMapEntryI->second = std::move(copy);
        }

    }

    Create create;
    create->setArgs1(create_arg);
    create->setFrom(mAvatarId);
    create->setSerialno(newSerialNumber());

    mCreateEntityMapping.insert(std::make_pair(create->getSerialno(), obj->getId()));

    res.push_back(create);
}
コード例 #5
0
ファイル: Peer.cpp プロジェクト: erikogenvik/cyphesis
/// \brief Teleport an entity to the connected peer
///
/// @param ent The entity to be teleported
/// @return Returns 0 on success and -1 on failure
int Peer::teleportEntity(const Entity * ent)
{
    if (m_state != PEER_AUTHENTICATED) {
        log(ERROR, "Peer not authenticated yet.");
        return -1;
    }

    long iid = ent->getIntId();
    if (m_teleports.find(iid) != m_teleports.end()) {
        log(INFO, "Transfer of this entity already in progress");
        return -1;
    }

    struct timeval timeVal;
    gettimeofday(&timeVal, NULL);
    time_t teleport_time = timeVal.tv_sec;

    // Add a teleport state object to identify this teleport request
    TeleportState * s = new TeleportState(teleport_time);
    if (s == NULL) {
        log(ERROR, "Unable to allocate teleport state object");
        return -1;
    }

    // Check if the entity has a mind
    const Character * chr = dynamic_cast<const Character *>(ent);
    ExternalMind * mind = 0;
    if (chr != 0 && chr->m_externalMind != 0) {
        mind = dynamic_cast<ExternalMind*>(chr->m_externalMind);
    }

    Atlas::Objects::Entity::Anonymous atlas_repr;
    ent->addToEntity(atlas_repr);

    Create op;
    op->setFrom(m_accountId);
    op->setSerialno(iid);
    op->setArgs1(atlas_repr);
    
    if (mind != 0 && mind->isConnected()) {
        // Entities with a mind require an additional one-time possess key that
        // is used by the client to authenticate a teleport on the destination
        // peer
        std::string key;
        log(INFO, "Entity has a mind. Generating random key");
        // FIXME non-random, plus potetial timing attack.
        WFMath::MTRand generator;
        for(int i=0;i<32;i++) {
            char ch = (char)((int)'a' + generator.rand(25));
            key += ch;
        }

        s->setKey(key);
        // Add an additional possess key argument
        log(INFO, String::compose("Adding possess key %1 to Create op", key));
        Anonymous key_arg;
        key_arg->setAttr("possess_key", key);

        std::vector<Root> & create_args = op->modifyArgs();
        create_args.push_back(key_arg);
    }
    m_commClient.send(op);
    log(INFO, "Sent Create op to peer");
    
    // Set it as validated and add to the list of teleports
    s->setRequested();
    m_teleports[iid] = s;
    log(INFO, "Added new teleport state");

    return 0;
}
コード例 #6
0
ファイル: Interactive.cpp プロジェクト: 9cat/cyphesis
void Interactive::exec(const std::string & cmd, const std::string & arg)
{
    bool reply_expected = true;
    reply_flag = false;
    error_flag = false;

    boost::shared_ptr<ObjectContext> command_context = m_currentContext.lock();
    if (!command_context) {
        std::cout << "ERROR: Context free" << std::endl << std::flush;
        return;
    }

    if (cmd == "stat") {
        Get g;
        send(g);
    } else if (cmd == "install") {
        size_t space = arg.find(' ');
        if (space == std::string::npos || space >= (arg.size() - 1)) {
            std::cout << "usage: install <type id> <parent id>"
                      << std::endl << std::flush;
        } else {
            Create c;
            c->setFrom(m_accountId);
            Anonymous ent;
            ent->setId(std::string(arg, 0, space));
            ent->setObjtype("class");
            ent->setParents(std::list<std::string>(1, std::string(arg, space + 1)));
            c->setArgs1(ent);
            send(c);
        }
        reply_expected = false;
    } else if (cmd == "look") {
        Look l;
        if (!arg.empty()) {
            Anonymous cmap;
            cmap->setId(arg);
            l->setArgs1(cmap);
        }
        l->setSerialno(newSerialNo());
        command_context->setFromContext(l);
        send(l);
        reply_expected = false;
    } else if (cmd == "logout") {
        Logout l;
        l->setFrom(m_accountId);
        if (!arg.empty()) {
            Anonymous lmap;
            lmap->setId(arg);
            l->setArgs1(lmap);
            reply_expected = false;
        }
        send(l);
    } else if (cmd == "say") {
        Talk t;
        Anonymous ent;
        ent->setAttr("say", arg);
        t->setArgs1(ent);
        t->setFrom(m_accountId);
        send(t);
    } else if (cmd == "help" || cmd == "?") {
        reply_expected = false;
        help();
    } else if (cmd == "query") {
        Get g;

        if (!arg.empty()) {
            Anonymous cmap;
            if (::isdigit(arg[0])) {
                cmap->setObjtype("obj");
            } else {
                cmap->setObjtype("meta");
            }
            cmap->setId(arg);
            g->setArgs1(cmap);
        }
        g->setFrom(m_accountId);

        send(g);
    } else if (cmd == "reload") {
        if (arg.empty()) {
            reply_expected = false;
            std::cout << "reload: Argument required" << std::endl << std::flush;
        } else {
            Set s;

            Anonymous tmap;
            tmap->setObjtype("class");
            tmap->setId(arg);
            s->setArgs1(tmap);
            s->setFrom(m_accountId);

            send(s);
        }
    } else if (cmd == "get") {
        Get g;

        if (!arg.empty()) {
            Anonymous cmap;
            if (::isdigit(arg[0])) {
                cmap->setObjtype("obj");
            } else {
                cmap->setObjtype("meta");
            }
            cmap->setId(arg);
            g->setArgs1(cmap);
        }
        g->setFrom(m_accountId);

        send(g);
    } else if (cmd == "monitor") {
        ClientTask * task = new OperationMonitor;
        if (runTask(task, arg) == 0) {
            Monitor m;

            m->setArgs1(Anonymous());
            m->setFrom(m_accountId);

            send(m);
        }

        reply_expected = false;
    } else if (cmd == "unmonitor") {
        OperationMonitor * om = dynamic_cast<OperationMonitor *>(m_currentTask);

        if (om != 0) {
            Monitor m;

            m->setFrom(m_accountId);

            send(m);

            reply_expected = false;

            SystemTime now;
            now.update();

            time_t monitor_time = now.seconds() - om->startTime();

            std::cout << om->count() << " operations monitored in "
                      << monitor_time << " seconds = "
                      << om->count() / monitor_time
                      << " operations per second"
                      << std::endl << std::flush;

            endTask();
        }
    } else if (cmd == "connect") {
        std::vector<std::string> args;
        tokenize(arg, args);

        if (args.size() != 2) {
            std::cout << "usage: connect <hostname> <port>"
                      << std::endl << std::flush;

            reply_expected = false;
        } else {
            Anonymous cmap;
            cmap->setAttr("hostname", args[0]);
            cmap->setAttr("port", strtol(args[1].c_str(), 0, 10));

            Connect m;
            m->setArgs1(cmap);
            // No serialno yet
            // FIXME add serialno once Juncture context can handle this

            command_context->setFromContext(m);

            send(m);
        }
    } else if (cmd == "add_agent") {
        std::string agent_type("creator");

        if (!arg.empty()) {
            agent_type = arg;
        }
        
        Create c;

        Anonymous cmap;
        cmap->setParents(std::list<std::string>(1, agent_type));
        cmap->setName("cycmd agent");
        cmap->setObjtype("obj");
        c->setArgs1(cmap);
        c->setSerialno(newSerialNo());

        command_context->setFromContext(c);

        send(c);
    } else if (cmd == "delete") {
        if (arg.empty()) {
            std::cout << "Please specify the entity to delete" << std::endl << std::flush;
            reply_expected = false;
        } else {
            Delete del;

            Anonymous del_arg;
            del_arg->setId(arg);
            del->setArgs1(del_arg);

            command_context->setFromContext(del);

            send(del);

            reply_expected = false;
        }
    } else if (cmd == "find_by_name") {
        if (arg.empty()) {
            std::cout << "Please specify the name to search for" << std::endl << std::flush;
            reply_expected = false;
        } else {
            Look l;

            Anonymous lmap;
            lmap->setName(arg);
            l->setArgs1(lmap);
            l->setSerialno(newSerialNo());

            command_context->setFromContext(l);

            send(l);

            reply_expected = false;
        }
    } else if (cmd == "find_by_type") {
        if (arg.empty()) {
            std::cout << "Please specify the type to search for" << std::endl << std::flush;
            reply_expected = false;
        } else {
            Look l;

            Anonymous lmap;
            lmap->setParents(std::list<std::string>(1, arg));
            l->setArgs1(lmap);
            l->setSerialno(newSerialNo());

            command_context->setFromContext(l);

            send(l);

            reply_expected = false;
        }
    } else if (cmd == "flush") {
        if (arg.empty()) {
            // FIXME usage
            std::cout << "Please specify the type to flush" << std::endl << std::flush;
            reply_expected = false;
        } else {
            ClientTask * task = new Flusher(command_context);
            runTask(task, arg);
            reply_expected = false;
        }
    } else if (cmd == "cancel") {
        if (endTask() != 0) {
            std::cout << "No task currently running" << std::endl << std::flush;
        }
    } else if (cmd == "dump") {
        if (command_context->repr() != "avatar") {
            std::cout << "You must have an agent in the world in order to dump the world." << std::endl << std::flush;
        } else {
            //Extract the avatar id by "misusing" the setFromContext method
            Operation op;
            command_context->setFromContext(op);
            ClientTask * task = new EntityExporter(m_accountId, op->getFrom());
            runTask(task, "world.xml");
            reply_expected = false;
        }
    } else if (cmd == "restore") {
        if (command_context->repr() != "avatar") {
            std::cout << "You must have an agent in the world in order to dump the world." << std::endl << std::flush;
        } else {
            //Extract the avatar id by "misusing" the setFromContext method
            Operation op;
            command_context->setFromContext(op);
            ClientTask * task = new EntityImporter(m_accountId, op->getFrom());
            runTask(task, "world.xml");
            reply_expected = false;
        }
    } else if (cmd == "create") {
        std::vector<std::string> args;
        tokenize(arg, args);

        if (args.size() < 1) {
            std::cout << "usage: create <type> <params> ... "
                      << std::endl << std::flush;
        } else {
            Anonymous cmap;
            cmap->setParents(std::list<std::string>(1, args[0]));
            cmap->setObjtype("obj");

            Create c;
            c->setArgs1(cmap);
            c->setSerialno(newSerialNo());
            command_context->setFromContext(c);

            send(c);
        }
        reply_expected = false;
    } else if (cmd == "login") {
        std::vector<std::string> args;
        tokenize(arg, args);

        if (args.size() != 2) {
            std::cout << "usage: login <username> <password>"
                      << std::endl << std::flush;
            reply_expected = false;
        } else {
            Anonymous cmap;
            cmap->setAttr("username", args[0]);
            cmap->setAttr("password", args[1]);

            Login m;
            m->setArgs1(cmap);
            m->setSerialno(newSerialNo());

            command_context->setFromContext(m);

            send(m);
        }
    } else {
        reply_expected = false;
        std::cout << cmd << ": Command not known" << std::endl << std::flush;
    }

    if (!reply_expected) {
        updatePrompt();
        return;
    }
    // Wait for reply
    time_t wait_start_time = time(NULL);
    while (!reply_flag) {
       if (time(NULL) - wait_start_time > 5) {
           std::cout << cmd << ": No reply from server" << std::endl << std::flush;
           return;
       }
       if (select(false) != 0) {
           return;
       }
    }
}