Beispiel #1
0
void CreatorClient::del(const std::string & id)
{
    Delete op;
    Anonymous ent;
    ent->setId(id);
    op->setArgs1(ent);
    op->setFrom(getId());
    op->setTo(id);
    return send(op);
}
Beispiel #2
0
void World::clearWorld(OpVector & res) {
    log(INFO, "Clearing world; deleting all entities.");

    OpVector ignoredRes;
    auto& baseWorld = BaseWorld::instance();
    if (m_contains) {
        while (!m_contains->empty()) {

            auto& entity = *m_contains->begin();

            if (entity->isPerceptive()) {
                //Send a sight of a delete op to the entity so that it knows it has been deleted.
                Delete delOp;
                delOp->setTo(entity->getId());

                Anonymous delArg;
                delArg->setId(entity->getId());
                delOp->setArgs1(delArg);

                Sight sToEntity;
                sToEntity->setArgs1(delOp);
                sToEntity->setTo(entity->getId());
                entity->operation(sToEntity, ignoredRes);
            }
            baseWorld.delEntity(entity.get());
        }
    }

    //Remove all properties except for "id"
    auto propIter = m_properties.begin();
    while(propIter != m_properties.end())
    {
        if (propIter->first != "id") {
            auto prop = propIter->second;
            prop->remove(this, propIter->first);
            delete prop;
            m_properties.erase(propIter++);
        } else {
            ++propIter;
        }
    }

    CalendarProperty* calProp = new CalendarProperty();
    calProp->install(this, "calendar");
    m_properties["calendar"] = calProp;

    delete m_contains;
    m_contains = nullptr;

    log(INFO, "World cleared of all entities.");
}
Beispiel #3
0
void Flusher::operation(const Operation & op, OpVector & res)
{
    shared_ptr<ObjectContext> flush_context = m_context.lock();

    if (!flush_context) {
        m_complete = true;
        return;
    }

    if (op->getClassNo() == Atlas::Objects::Operation::SIGHT_NO) {
        // We have a sight op, check if its the sight of an entity we
        // want to delete.
        const std::vector<Root> & args = op->getArgs();
        if (args.empty()) {
            std::cerr << "Got empty sight" << std::endl << std::flush;
            return;
        }
        const Root & arg = args.front();
        assert(arg.isValid());
        RootEntity sight_ent = smart_dynamic_cast<RootEntity>(arg);
        if (!sight_ent.isValid()) {
            return;
        }
        if (!sight_ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
            std::cerr << "Got sight no ID" << std::endl << std::flush;
            return;
        }
        if (!sight_ent->hasAttrFlag(Atlas::Objects::PARENTS_FLAG)) {
            std::cerr << "Got sight no PARENTS" << std::endl << std::flush;
            return;
        }
        if (sight_ent->getParents().empty() ||
                sight_ent->getParents().front() != type) {
            return;
        }
        const std::string & id = sight_ent->getId();

        std::cout << "Deleting: " << type << "(" << id << ")"
                  << std::endl << std::flush;

        // Send a delete to the entity we have seen.
        Delete d;

        Anonymous dmap;
        dmap->setId(id);
        d->setArgs1(dmap);

        flush_context->setFromContext(d);

        d->setTo(id);

        res.push_back(d);

        // Send a tick for a short time in the future so that
        // we can look again once this entity is definitly gone.
        Tick t;

        Anonymous tick_arg;
        tick_arg->setName("flusher");

        flush_context->setFromContext(t);
        t->setTo(t->getFrom());
        t->setFutureSeconds(0.1);
        t->setArgs1(tick_arg);

        res.push_back(t);
    } else if (op->getParents().front() == "tick") {
        // We have a tick op, check if its the one we sent ourselves
        // to schedule the next look.
        if (op->getArgs().empty() ||
                op->getArgs().front()->getName() != "flusher") {
            std::cout << "Not for us" << std::endl << std::flush;
            return;
        }

        // Send another look by type.
        Look l;

        Anonymous lmap;
        lmap->setParents(std::list<std::string>(1, type));
        l->setArgs1(lmap);
        flush_context->setFromContext(l);

        res.push_back(l);
    } else if (op->getParents().front() == "unseen") {
        // We have an unseen op, which signals our last look returned
        // no results.
        m_complete = true;
    }
}
Beispiel #4
0
/// \brief Handle an Info op response sent as reply to a teleport request
///
/// @param op The Info op sent back as reply to a teleport request
/// @param res The result set of replies
void Peer::peerTeleportResponse(const Operation &op, OpVector &res)
{
    log(INFO, "Got a peer teleport response");
    // Response to a Create op
    const std::vector<Root> & args = op->getArgs();
    if (args.size() < 1) {
        log(ERROR, "Malformed args in Info op");
        return;
    }
    const Root & arg = args.front();

    if (op->isDefaultRefno()) {
        log(ERROR, "Response to teleport has no refno");
        return;
    }

    long iid = op->getRefno();

    CommPeer *peer = dynamic_cast<CommPeer*>(&m_commClient);
    if(peer == 0) {
        log(ERROR, "Unable to get CommPeer object");
        return;
    }

    TeleportMap::iterator I = m_teleports.find(iid);
    if (I == m_teleports.end()) {
        log(ERROR, "Info op for unknown create");
        return;
    }

    TeleportState *s = I->second;
    assert (s != NULL);

    s->setCreated();
    log(INFO, String::compose("Entity with ID %1 replicated on peer", iid));

    // This is the sender entity. This is retreived again rather than
    // relying on a pointer (in the TeleportState object perhaps) as the
    // entity might have been deleted in the time between sending and response
    Entity * entity = BaseWorld::instance().getEntity(iid);
    if (entity == 0) {
        log(ERROR, String::compose("No entity found with ID: %1", iid));
        // Clean up the teleport state object
        m_teleports.erase(I);
        return;
    }

    // If entity has a mind, add extra information in the Logout op
    if (s->isMind()) {
        Character * chr = dynamic_cast<Character *>(entity);
        if (!chr) {
            log(ERROR, "Entity is not a character");
            return;
        }
        if (chr->m_externalMind == 0) {
            log(ERROR, "No external mind (though teleport state claims it)");
            return;
        }
        ExternalMind * mind = dynamic_cast<ExternalMind*>(chr->m_externalMind);
        if (mind == 0 || !mind->isConnected()) {
            log(ERROR, "Mind is NULL or not connected");
            return;
        }
        std::vector<Root> logout_args;

        Anonymous op_arg;
        op_arg->setId(entity->getId());
        logout_args.push_back(op_arg);

        Anonymous ip_arg;
        ip_arg->setAttr("teleport_host", peer->getHost());
        ip_arg->setAttr("teleport_port", peer->getPort());
        ip_arg->setAttr("possess_key", s->getPossessKey());
        ip_arg->setAttr("possess_entity_id", arg->getId());
        logout_args.push_back(ip_arg);

        Logout logoutOp;
        logoutOp->setArgs(logout_args);
        logoutOp->setTo(entity->getId());
        OpVector temp;
        mind->operation(logoutOp, temp);
        log(INFO, "Sent random key to connected mind");
    }

    // FIXME Remove from the world cleanly, not delete.

    // Delete the entity from the current world
    Delete delOp;
    Anonymous del_arg;
    del_arg->setId(entity->getId());
    delOp->setArgs1(del_arg);
    delOp->setTo(entity->getId());
    entity->sendWorld(delOp);
    log(INFO, "Deleted entity from current server");
    logEvent(EXPORT_ENT, String::compose("%1 - %2 Exported entity",
                                         getId(), entity->getId()));

    // Clean up the teleport state object
    m_teleports.erase(I);
}