Пример #1
0
void ConnectionCharacterintegration::test_connected()
{
    // Dispatching an external op from the character should have no effect
    // if the external mind is already in place.

    m_character->linkExternal(m_connection);

    ASSERT_NOT_NULL(m_character->m_externalMind);
    ExternalMind * em =
          dynamic_cast<ExternalMind*>(m_character->m_externalMind);
    ASSERT_NOT_NULL(em);
    ASSERT_TRUE(em->isLinked());
    ASSERT_TRUE(em->isLinkedTo(m_connection));

    Router * saved_em = m_character->m_externalMind;

    RootOperation op;
    op->setFrom(m_character->getId());

    m_connection->externalOperation(op, *m_connection);

    ASSERT_TRUE(!m_Link_send_sent.isValid());
    ASSERT_NOT_EQUAL(m_logEvent_logged, TAKE_CHAR);
    ASSERT_NOT_NULL(m_character->m_externalMind);
    ASSERT_EQUAL(m_character->m_externalMind, saved_em);
    em = dynamic_cast<ExternalMind*>(m_character->m_externalMind);
    ASSERT_NOT_NULL(em);
    ASSERT_TRUE(em->isLinked());
    ASSERT_TRUE(em->isLinkedTo(m_connection));
}
Пример #2
0
void ClientConnection::createCharacter(const RootOperation& op)
{
    static unsigned int charCounter = 0;
    char charId[64];
    ::snprintf(charId, 64, "_customChar_%d", ++charCounter);
    
    RootEntity ent = smart_dynamic_cast<RootEntity>(op->getArgs().front());
    
    ent->setId(charId);
    ent->setLoc("_world");
    m_server->m_world[charId] = ent;

    StringList children(m_server->m_world["_world"]->getContains());
    children.push_back(charId);
    m_server->m_world["_world"]->setContains(children);

    Agent* ag = new Agent(this, charId);
    ag->setEntityVisible(charId, true);
    
    m_agents[charId] = ag;
    
    Info info;
    info->setArgs1(m_server->m_world[charId]);
    info->setFrom(charId);
    info->setTo(m_account); // I *think* this is right
    info->setRefno(op->getSerialno());
    
    send(info);
}
Пример #3
0
void ClientConnection::poll()
{
    if (m_stream.eof()) {
        fail();
        return;
    }
    
    if (m_acceptor)
    {
        negotiate();
    }
    else
    {
        m_codec->poll();
        
        while (!m_objDeque.empty())
        {
            RootOperation op = smart_dynamic_cast<RootOperation>(m_objDeque.front());
            if (!op.isValid())
                throw InvalidOperation("ClientConnection recived something that isn't an op");
            
            dispatch(op);
            m_objDeque.pop_front();
        }
    }
}
Пример #4
0
void ServerAccounttest::test_createObject_success_refo()
{
    long cid = m_id_counter++;
    TestWorld_addNewEntity_ret_value = new Character(compose("%1", cid), cid);

    std::string type_str("unimportant_string");
    RootEntity arg;
    RootOperation op;
    op->setSerialno(44295);
    OpVector res;

    m_account->createObject(type_str, arg, op, res);

    ASSERT_EQUAL(res.size(), 1u);

    const RootOperation & reply = res.front();

    ASSERT_EQUAL(reply->getClassNo(),
                 Atlas::Objects::Operation::INFO_NO);
    ASSERT_TRUE(!reply->isDefaultRefno());
    ASSERT_EQUAL(reply->getRefno(), op->getSerialno());

    delete TestWorld_addNewEntity_ret_value;
    TestWorld_addNewEntity_ret_value = 0;
}
Пример #5
0
void ServerAccounttest::test_createObject_success_possess()
{
    long cid = m_id_counter++;
    TestWorld_addNewEntity_ret_value = new Character(compose("%1", cid), cid);

    std::string type_str("unimportant_string");
    RootEntity arg;
    RootEntity arg2;
    arg2->setAttr("possess_key", "unimportant_string");
    RootOperation op;
    op->setArgs1(arg);
    op->modifyArgs().push_back(arg2);
    OpVector res;

    m_account->createObject(type_str, arg, op, res);


    ASSERT_EQUAL(res.size(), 1u);

    const RootOperation & reply = res.front();

    ASSERT_EQUAL(reply->getClassNo(),
                 Atlas::Objects::Operation::INFO_NO);

    delete TestWorld_addNewEntity_ret_value;
    TestWorld_addNewEntity_ret_value = 0;
}
Пример #6
0
bool AccountContext::accept(const RootOperation& op) const
{
    std::cout << "Checking account context to see if it matches"
              << std::endl << std::flush;
    if (m_refNo != 0L && !op->isDefaultRefno() && op->getRefno() == m_refNo) {
        return true;
    }
    return false;
}
Пример #7
0
void Connection::postForDispatch(const Root& obj)
{
    RootOperation op = smart_dynamic_cast<RootOperation>(obj);
    assert(op.isValid());
    m_opDeque.push_back(op);

#ifdef ATLAS_LOG
    std::stringstream debugStream;
    Atlas::Codecs::Bach debugCodec(debugStream, *this /* dummy */);
    Atlas::Objects::ObjectsEncoder debugEncoder(debugCodec);
    debugEncoder.streamObjectsMessage(obj);
    debugStream << std::flush;

    std::cout << "posted for re-dispatch:" << debugStream.str() << std::endl;
#endif
}
Пример #8
0
void ClientConnection::activateCharacter(const std::string& charId, const RootOperation& op)
{
    // special magic testing IDs
    if (charId == "_fail_") {
        sendError("deliberate", op);
        return;
    }

    assert(entityIsCharacter(charId));
    //debug() << "activation, inbound op's serial is " << op->getSerialno();
    
    if (m_agents.count(charId)) {
        sendError("duplicate character action", op);
        return;
    }
    
    Agent* ag = new Agent(this, charId);
    m_agents[charId] = ag;
    
    Info info;
    info->setArgs1(m_server->m_world[charId]);
    info->setFrom(charId);
    info->setTo(m_account); // I *think* this is right
    info->setRefno(op->getSerialno());
    
    send(info);
    ag->processOp(op); // process as normal
}
Пример #9
0
void ClientConnection::sendError(const std::string& msg, const RootOperation& op)
{
    Error errOp;
    
    errOp->setRefno(op->getSerialno());
    errOp->setTo(op->getFrom());
    
    Root arg0;
    arg0->setAttr("message", msg);
    
    std::vector<Root>& args = errOp->modifyArgs();
    args.push_back(arg0);
    args.push_back(op);
    
    send(errOp);
}
Пример #10
0
void Connection::objectArrived(const Root& obj)
{
#ifdef ATLAS_LOG
    std::stringstream debugStream;
    Atlas::Codecs::Bach debugCodec(debugStream, *this /* dummy */);
    Atlas::Objects::ObjectsEncoder debugEncoder(debugCodec);
    debugEncoder.streamObjectsMessage(obj);
    debugStream << std::flush;

    std::cout << "received:" << debugStream.str() << std::endl;
#endif
    RootOperation op = smart_dynamic_cast<RootOperation>(obj);
    if (op.isValid()) {
        m_opDeque.push_back(op);
    } else
        error() << "Con::objectArrived got non-op";
}
Пример #11
0
void ClientConnection::dispatchOOG(const RootOperation& op)
{
    switch (op->getClassNo()) {
    case LOOK_NO:
        processOOGLook(smart_dynamic_cast<Look>(op));
        return;
    
    case MOVE_NO:
        return;
        
    case TALK_NO: {
        Talk tk = smart_dynamic_cast<Talk>(op);
        processTalk(tk);
        return;
    }
   
    case LOGOUT_NO: {
        Logout logout = smart_dynamic_cast<Logout>(op);
        
        Info logoutInfo;
        logoutInfo->setArgs1(logout);
        logoutInfo->setTo(m_account);
        logoutInfo->setRefno(logout->getSerialno());
        send(logoutInfo);
        return;
    }
    
    case CREATE_NO: {
        const StringList& arg0Parents(op->getArgs().front()->getParents());
        if (arg0Parents.front() == "__fail__") {
            sendError("bad type for char creation", op);
            return;
        }
        
        if (arg0Parents.front() == "settler") {
            createCharacter(op);
            return;
        }
    }
    
    default:
        error() << "clientConnection failed to handle OOG op";
    } // of classNo switch
}
Пример #12
0
LocatedEntity * CreatorClient::make(const RootEntity & entity)
{
    Create op;
    op->setArgs1(entity);
    op->setFrom(getId());
    op->setTo(getId());
    OpVector result;
    if (sendAndWaitReply(op, result) != 0) {
        std::cerr << "No reply to make" << std::endl << std::flush;
        return NULL;
    }
    assert(!result.empty());
    const Operation & res = result.front();
    if (!res.isValid()) {
        std::cerr << "NULL reply to make" << std::endl << std::flush;
        return NULL;
    }
    // FIXME Make this more robust against an info response
    if (res->getClassNo() == Atlas::Objects::Operation::SIGHT_NO) {
        if (res->getArgs().empty()) {
            std::cerr << "Reply to make has no args" << std::endl << std::flush;
            return NULL;
        }
        RootOperation arg = smart_dynamic_cast<RootOperation>(res->getArgs().front());
        if (!arg.isValid()) {
            std::cerr << "Arg of reply to make is not an operation"
                      << std::endl << std::flush;
            return NULL;
        }
        if (arg->getClassNo() != Atlas::Objects::Operation::CREATE_NO) {
            std::cerr << "Reply to make isn't sight of create"
                      << std::endl << std::flush;
            return NULL;
        }
        return handleMakeResponse(arg, res->getSeconds());
    } else if (res->getClassNo() == Atlas::Objects::Operation::INFO_NO) {
        return handleMakeResponse(res, res->getSeconds());
    } else {
        std::cerr << "Reply to make isn't sight or info"
                  << std::endl << std::flush;
        return NULL;
    }
}
Пример #13
0
void Connection::handleServerInfo(const RootOperation& op)
{
    RootEntity svr = smart_dynamic_cast<RootEntity>(op->getArgs().front());
    if (!svr.isValid()) {
        error() << "server INFO argument object is broken";
        return;
    }

    m_info.processServer(svr);
    GotServerInfo.emit();
}
Пример #14
0
void ServerAccounttest::test_createObject_no_possess()
{
    long cid = m_id_counter++;
    TestWorld_addNewEntity_ret_value = new Character(compose("%1", cid), cid);

    std::string type_str("unimportant_string");
    RootEntity arg;
    RootEntity arg2;
    RootOperation op;
    op->setArgs1(arg);
    op->modifyArgs().push_back(arg2);
    OpVector res;

    m_account->createObject(type_str, arg, op, res);

    // FIXME No error to the client!
    ASSERT_TRUE(res.empty());

    delete TestWorld_addNewEntity_ret_value;
    TestWorld_addNewEntity_ret_value = 0;
}
Пример #15
0
/// \brief Function call from the base class when an object arrives from the
/// server
///
/// @param obj Object that has arrived from the server
void AtlasStreamClient::objectArrived(const Root & obj)
{
    RootOperation op = Atlas::Objects::smart_dynamic_cast<RootOperation>(obj);
    if (!op.isValid()) {
        std::cerr << "ERROR: Non op object received from server"
                  << std::endl << std::flush;;
        if (!obj->isDefaultParents() && !obj->getParents().empty()) {
            std::cerr << "NOTICE: Unexpected object has parent "
                      << obj->getParents().front()
                      << std::endl << std::flush;
        }
        if (!obj->isDefaultObjtype()) {
            std::cerr << "NOTICE: Unexpected object has objtype "
                      << obj->getObjtype()
                      << std::endl << std::flush;
        }
        return;
    }

    mOps.push_back(op);
}
Пример #16
0
void Commander::recv()
{
    if (m_channel.eof()) return;
        
    if (m_acceptor)
        negotiate();
    else {
        m_codec->poll();
        
        while (!m_objDeque.empty())
        {
            RootOperation op = smart_dynamic_cast<RootOperation>(m_objDeque.front());
            if (!op.isValid())
                throw InvalidOperation("Commander received something that isn't an op");
            
            dispatch(op);
            
            m_objDeque.pop_front();
        }
    }
}
Пример #17
0
void ClientConnection::operation(const RootOperation & op)
{
    if (debug_flag) {
        std::stringstream ss;
        ss << "I: " << op->getParents().front() << " : ";
        Atlas::Message::QueuedDecoder decoder;
        Atlas::Codecs::XML codec(ss, ss, decoder);

        Atlas::Objects::ObjectsEncoder encoder(codec);
        encoder.streamObjectsMessage(op);
        ss << std::flush;
        debug(std::cerr << ss.str() << std::endl;);
    }
Пример #18
0
Router::RouterResult EntityRouter::handleSightOp(const RootOperation& op)
{
    const std::vector<Root>& args = op->getArgs();
    
    if (op->getClassNo() == MOVE_NO) {

        //If we get a MOVE op for an entity that's not visible, it means that the entity has moved
        //within our field of vision without sending an Appear op first. We should treat this as a
        //regular Appear op and issue a Look op back, to get more info.
        if (!m_entity->isVisible()) {
            m_entity->getView()->sendLookAt(m_entity->getId());
        }
        // sight of move, we handle as a specialization of set.
        assert(!args.empty());
        const Root & arg = args.front();
        
        // break out LOC, which MOVE ops are allowed to update
        if (arg->hasAttr("loc")) {
            m_entity->setLocationFromAtlas(arg->getAttr("loc").asString());
        }
        
        m_entity->setFromRoot(arg, true /* movement allowed */);
        return HANDLED;
    }
    
    if (op->instanceOf(IMAGINARY_NO)) {
        if (args.empty())
            error() << "entity " << m_entity->getId() << " sent imaginary with no args: " << op;
        else
            m_entity->onImaginary(args.front());
        return HANDLED;        
    }
    
    // explicitly do NOT handle set ops here, since they can
    // validly change multiple entities - handled by the IGRouter

    return IGNORED;
}
Пример #19
0
void ConnectionCharacterintegration::test_connect_up()
{
    // Dispatching an external op from the character should cause it to
    // get connected up with an external mind

    RootOperation op;
    op->setFrom(m_character->getId());

    ASSERT_NULL(m_character->m_externalMind);

    m_connection->externalOperation(op, *m_connection);

    ASSERT_NOT_NULL(m_character->m_externalMind);
    ExternalMind * em =
          dynamic_cast<ExternalMind*>(m_character->m_externalMind);
    ASSERT_NOT_NULL(em);
    ASSERT_TRUE(em->isLinked());
    ASSERT_TRUE(em->isLinkedTo(m_connection));
    ASSERT_TRUE(m_Link_send_sent.isValid());
    ASSERT_EQUAL(m_Link_send_sent->getClassNo(),
                 Atlas::Objects::Operation::INFO_NO);
    ASSERT_EQUAL(m_logEvent_logged, TAKE_CHAR);
}
Пример #20
0
/// \brief Called when an Error operation arrives
///
/// @param op Operation to be processed
void AtlasStreamClient::errorArrived(const RootOperation & op)
{
    reply_flag = true;
    error_flag = true;
    const std::vector<Root> & args = op->getArgs();
    if (args.empty()) {
        return;
    }
    const Root & arg = args.front();
    Element message_attr;
    if (arg->copyAttr("message", message_attr) == 0 && message_attr.isString()) {
        m_errorMessage = message_attr.String();
    }
}
Пример #21
0
void ConnectionCharacterintegration::test_unlinked()
{
    // Dispatching an external op from the character if the external mind is
    // already in place, but is not linked to a connection should link it
    // back up.

    m_character->linkExternal(m_connection);

    ASSERT_NOT_NULL(m_character->m_externalMind);
    ExternalMind * em =
          dynamic_cast<ExternalMind*>(m_character->m_externalMind);
    ASSERT_NOT_NULL(em);
    ASSERT_TRUE(em->isLinked());
    ASSERT_TRUE(em->isLinkedTo(m_connection));

    // Remove the link from the external mind back to m_connection
    em->linkUp(0);

    ASSERT_TRUE(!em->isLinked());

    Router * saved_em = m_character->m_externalMind;

    RootOperation op;
    op->setFrom(m_character->getId());

    m_connection->externalOperation(op, *m_connection);

    ASSERT_NOT_NULL(m_character->m_externalMind);
    ASSERT_EQUAL(m_character->m_externalMind, saved_em);
    em = dynamic_cast<ExternalMind*>(m_character->m_externalMind);
    ASSERT_NOT_NULL(em);
    ASSERT_TRUE(em->isLinked());
    ASSERT_TRUE(em->isLinkedTo(m_connection));
    ASSERT_TRUE(m_Link_send_sent.isValid());
    ASSERT_EQUAL(m_logEvent_logged, TAKE_CHAR);
}
Пример #22
0
void AtlasStreamClient::operation(const RootOperation & op)
{
    if (m_currentTask != 0) {
        OpVector res;
        m_currentTask->operation(op, res);
        OpVector::const_iterator Iend = res.end();
        for (OpVector::const_iterator I = res.begin(); I != Iend; ++I) {
            send(*I);
        }

        if (m_currentTask->isComplete()) {
            delete m_currentTask;
            m_currentTask = 0;
        }
    }

    switch (op->getClassNo()) {
        case Atlas::Objects::Operation::APPEARANCE_NO:
            appearanceArrived(op);
            break;
        case Atlas::Objects::Operation::DISAPPEARANCE_NO:
            disappearanceArrived(op);
            break;
        case Atlas::Objects::Operation::INFO_NO:
            infoArrived(op);
            break;
        case Atlas::Objects::Operation::ERROR_NO:
            errorArrived(op);
            break;
        case Atlas::Objects::Operation::SIGHT_NO:
            sightArrived(op);
            break;
        case Atlas::Objects::Operation::SOUND_NO:
            soundArrived(op);
            break;
        default:
            break;
    }
}
Пример #23
0
void AtlasStreamClient::infoArrived(const RootOperation & op)
{
    reply_flag = true;
    if (!op->isDefaultFrom()) {
        return;
    }
    if (op->isDefaultArgs() || op->getArgs().empty()) {
        std::cerr << "WARNING: Malformed account from server" << std::endl << std::flush;
        return;
    }
    if (op->isDefaultRefno()) {
        return;
    }
    if (op->getRefno() != serialNo) {
        return;
    }
    m_infoReply = op->getArgs().front();
}
Пример #24
0
void Connection::dispatchOp(const RootOperation& op)
{
    try {
        Router::RouterResult rr = Router::IGNORED;
        bool anonymous = op->isDefaultTo();

        if (m_responder->handleOp(op)) return;

    // locate a router based on from
        if (!op->isDefaultFrom()) {
            IdRouterMap::const_iterator R = m_fromRouters.find(op->getFrom());
            if (R != m_fromRouters.end()) {
                rr = R->second->handleOperation(op);
                if ((rr == Router::HANDLED) || (rr == Router::WILL_REDISPATCH)) return;
            }
        }

    // locate a router based on the op's TO value
        if (!anonymous) {
            IdRouterMap::const_iterator R = m_toRouters.find(op->getTo());
            if (R != m_toRouters.end()) {
                rr = R->second->handleOperation(op);
                if ((rr == Router::HANDLED) || (rr == Router::WILL_REDISPATCH)) return;
            } else if (!m_toRouters.empty()) {
                warning() << "recived op with TO=" << op->getTo() << ", but no router is registered for that id";
            }
        }

    // special-case, server info refreshes are handled here directly
        if (op->instanceOf(INFO_NO) && anonymous) {
            handleServerInfo(op);
            return;
        }

    // go to the default router
        if (m_defaultRouter) rr = m_defaultRouter->handleOperation(op);
        if (rr != Router::HANDLED) warning() << "no-one handled op:" << op;
    } catch (Atlas::Exception& ae) {
        error() << "caught Atlas exception: " << ae.getDescription() <<
            " while dispatching op:\n" << op;
    }
}
Пример #25
0
Router::RouterResult EntityRouter::handleOperation(const RootOperation& op)
{
    assert(op->getFrom() == m_entity->getId());    
    const std::vector<Root>& args = op->getArgs();
    
    // note it's important we match exactly on sight here, and not deried ops
    // like appearance and disappearance
    if (op->getClassNo() == SIGHT_NO) {
        assert(!args.empty());
        RootOperation sop = smart_dynamic_cast<RootOperation>(args.front());
        if (sop.isValid()) return handleSightOp(sop);
    }
    
    if (op->getClassNo() == SOUND_NO) {
        assert(!args.empty());
        if (args.front()->getClassNo() == TALK_NO)
        {
            RootOperation talk = smart_dynamic_cast<RootOperation>(args.front());
            m_entity->onTalk(talk);
            return HANDLED;
        } 
        
        TypeInfo* ty = typeService()->getTypeForAtlas(args.front());
        if (!ty->isBound()) {
            new TypeBoundRedispatch(m_entity->getView()->getAvatar()->getConnection(), op, ty);
            return WILL_REDISPATCH;
        }
    
        if (ty->isA(typeService()->getTypeByName("action")))
        {
            // sound of action
            RootOperation act = smart_dynamic_cast<RootOperation>(args.front());
            m_entity->onSoundAction(act);
            return HANDLED;
        }
        
        warning() << "entity " << m_entity->getId() << " emitted sound with strange argument: " << op;
        // other sounds !
    }

    return IGNORED;
}
Пример #26
0
int AccountContext::dispatch(const RootOperation & op)
{
    std::cout << "Dispatching with account context to see if it matches"
              << std::endl << std::flush;
    if (op->getClassNo() == Atlas::Objects::Operation::INFO_NO &&
        !op->getArgs().empty()) {
        std::cout << "Dispatching info"
                  << std::endl << std::flush;
        const Root & ent = op->getArgs().front();
        if (ent->hasAttrFlag(Atlas::Objects::ID_FLAG) &&
            ent->hasAttrFlag(Atlas::Objects::PARENTS_FLAG) &&
            ent->getParents().size() > 0) {
            const std::string & type = ent->getParents().front();
            if (type == "juncture") {
                std::cout << "created juncture"
                          << std::endl << std::flush;
                m_client.addCurrentContext(shared_ptr<ObjectContext>(
                      new JunctureContext(m_client, ent->getId())));
            } else {
                std::cout << "created avatar"
                          << std::endl << std::flush;
                m_client.addCurrentContext(shared_ptr<ObjectContext>(
                      new AvatarContext(m_client, ent->getId())));
                
            }
        } else {
            // FIXME Report an error?
        }
    } else if (op->getClassNo() == Atlas::Objects::Operation::SIGHT_NO &&
               !op->getArgs().empty()) {
        std::cout << "Sight(" << std::endl;
        m_client.output(op->getArgs().front());
        std::cout << ")" << std::endl << std::flush;
    }
    assert(m_refNo != 0L);
    m_refNo = 0L;
    return 0;
}
Пример #27
0
LocatedEntity * CreatorClient::make(const RootEntity & entity)
{
    Create op;
    op->setArgs1(entity);
    op->setFrom(getId());
    op->setTo(getId());
    OpVector result;
    if (sendAndWaitReply(op, result) != 0) {
        std::cerr << "No reply to make" << std::endl << std::flush;
        return NULL;
    }
    assert(!result.empty());
    const Operation & res = result.front();
    if (!res.isValid()) {
        std::cerr << "NULL reply to make" << std::endl << std::flush;
        return NULL;
    }
    if (res->getClassNo() != Atlas::Objects::Operation::SIGHT_NO) {
        std::cerr << "Reply to make isn't sight" << std::endl << std::flush;
        return NULL;
    }
    if (res->getArgs().empty()) {
        std::cerr << "Reply to make has no args" << std::endl << std::flush;
        return NULL;
    }
    RootOperation arg = smart_dynamic_cast<RootOperation>(res->getArgs().front());
    if (!arg.isValid()) {
        std::cerr << "Arg of reply to make is not an operation"
                  << std::endl << std::flush;
        return NULL;
    }
    if (arg->getClassNo() != Atlas::Objects::Operation::CREATE_NO) {
        std::cerr << "Reply to make isn't sight of create"
                  << std::endl << std::flush;
        return NULL;
    }
    if (arg->getArgs().empty()) {
        std::cerr << "Arg of reply to make has no args"
                  << std::endl << std::flush;
        return NULL;
    }
    RootEntity created = smart_dynamic_cast<RootEntity>(arg->getArgs().front());
    if (!created.isValid()) {
        std::cerr << "Created argument is not an entity"
                  << std::endl << std::flush;
        return NULL;
    }
    if (!created->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
        std::cerr << "Created entity has no id"
                  << std::endl << std::flush;
        return NULL;
    }
    const std::string & created_id = created->getId();
    if (created->getParents().empty()) {
        std::cerr << "Created entity " << created_id << " has no type"
                  << std::endl << std::flush;
        return NULL;
    }
    const std::string & created_type = created->getParents().front();
    std::cout << "Created: " << created_type << "(" << created_id << ")"
              << std::endl << std::flush;
    LocatedEntity * obj = m_map.updateAdd(created, res->getSeconds());
    return obj;
}
Пример #28
0
void ClientConnection::dispatch(const RootOperation& op)
{    
    const std::vector<Root>& args = op->getArgs();
    
    if (op->getFrom().empty())
    {        
        if (m_account.empty())
        {
            // not logged in yet
            if (op->getClassNo() == LOGIN_NO) {
                processLogin(smart_dynamic_cast<Login>(op));
                return;
            }
       
            if (op->getClassNo() == CREATE_NO) {
                assert(!args.empty());
                processAccountCreate(smart_dynamic_cast<Create>(op));
                return;
            }
        }
        
        if (op->getClassNo() == GET_NO) {
            processAnonymousGet(smart_dynamic_cast<Get>(op));
            return;
        }
        
        if (op->getClassNo() == LOGOUT_NO) {
            return;
        }
        
        throw TestFailure("got anonymous op I couldn't dispatch");
    }
    
    if (op->getFrom() == m_account) {
        dispatchOOG(op);
        return;
    }
    
    if (m_agents.count(op->getFrom())) {
        m_agents[op->getFrom()]->processOp(op);
        return;
    }


    if (entityIsCharacter(op->getFrom())) {
        // IG activation
        activateCharacter(op->getFrom(), op);
        return;
    }
    
        
    debug() << "totally failed to handle operation " << objectSummary(op);
}
Пример #29
0
void Commander::dispatch(const RootOperation& op)
{
    Appearance appear = smart_dynamic_cast<Appearance>(op);
    if (appear.isValid()) {
        assert(op->hasAttr("for"));
        Agent* ag = m_server->findAgentForEntity(op->getAttr("for").asString());
        if (ag) {
            ag->setEntityVisible(op->getTo(), true);
        } else {
            // doesn't exist yet, mark as visible if / when the agent is created
            Agent::setEntityVisibleForFutureAgent(op->getTo(), op->getAttr("for").asString());
        }
    }
    
    Disappearance disap = smart_dynamic_cast<Disappearance>(op);
    if (disap.isValid()) {
        assert(op->hasAttr("for"));
        Agent* ag = m_server->findAgentForEntity(op->getAttr("for").asString());
        if (ag) ag->setEntityVisible(op->getTo(), false);
    }
    
    Create cr = smart_dynamic_cast<Create>(op);
    if (cr.isValid()) {
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        RootEntity ent = smart_dynamic_cast<RootEntity>(args.front());
        assert(ent.isValid());
        
        static int idCounter = 900;
        char buf[32];
        snprintf(buf, 32, "_created_%d", ++idCounter);
        std::string id(buf);
        
        ent->setId(id);
        std::string loc = ent->getLoc();
        assert(m_server->m_world.count(loc));
        
        StringList children(m_server->m_world[loc]->getContains());
        children.push_back(id);
        m_server->m_world[loc]->setContains(children);

        m_server->m_world[id] = ent;
        
        Create bcr(cr);
        bcr->setArgs1(ent);
        Agent::broadcastSight(bcr);
    }
    
    Delete del = smart_dynamic_cast<Delete>(op);
    if (del.isValid()) {
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        
        std::string id = args.front()->getId();
        assert(m_server->m_world.count(id));
        m_server->m_world.erase(id);
        
        Agent::broadcastSight(op);
    }
    
    Move mv = smart_dynamic_cast<Move>(op);
    if (mv.isValid()) {
        RootEntity ent = m_server->getEntity(op->getTo());
        
        std::vector<Root> args(op->getArgs());
        
        if (args.front()->hasAttr("loc")) {
            std::string newLocId = args.front()->getAttr("loc").asString();
            
            RootEntity oldLoc = m_server->getEntity(ent->getLoc()),
                newLoc = m_server->getEntity(newLocId);
            
            ent->setLoc(newLocId);
            // modify stamps?
            oldLoc->modifyContains().remove(ent->getId());
            newLoc->modifyContains().push_back(ent->getId());
        }
        
        if (args.front()->hasAttr("pos"))
            ent->setPosAsList(args.front()->getAttr("pos").asList());
            
        // handle velocity changes
        Agent::broadcastSight(op);
        return;
    }
    
    Sound snd = smart_dynamic_cast<Sound>(op);
    if (snd.isValid()) {
        
        std::vector<Root> args(op->getArgs());
        assert(!args.empty());
        
        if (snd->hasAttr("broadcast")) {
            Agent::broadcastSound(smart_dynamic_cast<RootOperation>(args.front()));
        }
    }
    
    Sight st = smart_dynamic_cast<Sight>(op);
    if (st.isValid()) {
        if (st->hasAttr("broadcast")) {
            std::vector<Root> args(op->getArgs());
            assert(!args.empty());
            Agent::broadcastSight(smart_dynamic_cast<RootOperation>(args.front()));
        }
    }
    
    Set s = smart_dynamic_cast<Set>(op);
    if (s.isValid()) {
        
        std::vector<Root> args(op->getArgs());
        for (unsigned int A=0; A < args.size(); ++A) {
            std::string eid = args[A]->getId();
        
            RootEntity entity = m_server->getEntity(eid);
            Root::const_iterator I = args[A]->begin();
            
            for (; I != args[A]->end(); ++I) {
                if ((I->first == "id") || (I->first == "parents") || (I->first == "objtype")) {
                    continue;
                }
                
                assert(I->first != "loc");
                entity->setAttr(I->first, I->second);
            }
        }

        Agent::broadcastSight(s);
    }
    
    Action act = smart_dynamic_cast<Action>(op);
    if (act.isValid()) {
        std::vector<Root> args(op->getArgs());
        
        if (act->getParents().front() == "command") {
            std::string cid = args[0]->getAttr("cid").asString();
            
            if (cid == "socket-shutdown") {
                std::string acc = args[0]->getAttr("acc").asString();
                ClientConnection* cc = m_server->getConnectionForAccount(acc);
                assert(cc);
                cc->shutdown();
            } else if (cid == "add-many-objects") {
                m_server->addManyObjects(args[0]->getAttr("acc").asString());
            } else if (cid == "set-world-time") {
                /* double t = */ args[0]->getAttr("seconds").asFloat();
                
            } else {
                std::cerr << "unknown command " << cid << std::endl;
            }
        } // of command action case
    } // of action case
}