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