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