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);
}
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);
}
Exemple #3
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;
    }
}
Exemple #4
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;
}