示例#1
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);
}
示例#2
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;
}
示例#3
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;
}
示例#4
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
}
示例#5
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;
    }
}
示例#6
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;
    }
}
示例#7
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;
}
示例#8
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;
}