Example #1
0
static void addTypeToList(const Root & type, ListType & typeList)
{
    typeList.push_back(type->getId());
    Element children;
    if (type->copyAttr("children", children) != 0) {
        return;
    }
    if (!children.isList()) {
        log(ERROR, compose("Type %1 children attribute has type %2 instead of "
                           "string.", type->getId(),
                           Element::typeName(children.getType())));
        return;
    }
    ListType::const_iterator I = children.List().begin();
    ListType::const_iterator Iend = children.List().end();
    for (; I != Iend; ++I) {
        Root child = Inheritance::instance().getClass(I->asString());
        if (!child.isValid()) {
            log(ERROR, compose("Unable to find %1 in inheritance table",
                               I->asString()));
            continue;
        }
        addTypeToList(child, typeList);
    }
}
Example #2
0
void TrustedConnectionCreatorintegration::setup()
{
    m_Link_send_sent = 0;
    m_BaseWorld_message_called = 0;
    m_BaseWorld_message_called_from = 0;
    m_Entity_callOperation_called = 0;

    Entity * gw = new Entity(compose("%1", m_id_counter),
                             m_id_counter++);
    m_server = new ServerRouting(*new TestWorld(*gw),
                                 "dd7452be-0137-4664-b90e-77dfb395ac39",
                                 "a2feda8e-62e9-4ba0-95c4-09f92eda6a78",
                                 compose("%1", m_id_counter), m_id_counter++,
                                 compose("%1", m_id_counter), m_id_counter++);
    m_connection = new Connection(*(CommSocket*)0,
                                  *m_server,
                                  "25251955-7e8c-4043-8a5e-adfb8a1e76f7",
                                  compose("%1", m_id_counter), m_id_counter++);
    m_creator = new Creator(compose("%1", m_id_counter), m_id_counter++);
    m_creatorType = new TypeNode("test_avatar");
    m_creator->setType(m_creatorType);

    m_connection->addObject(m_creator);

    m_BaseWorld_message_called = 0;
    m_BaseWorld_message_called_from = 0;
}
Example #3
0
void TrustedConnectionCreatorintegration::test_external_op_puppet_nonexistant()
{
    // Dispatching a Talk external op from the creator, to the creator should
    // result in it being passed directly to the normal op dispatch,
    // shortcutting the world.

    m_creator->m_externalMind = new ExternalMind(*m_creator);
    m_creator->m_externalMind->linkUp(m_connection);

    Entity * other = new Entity(compose("%1", m_id_counter), m_id_counter++);
    other->setType(m_creatorType);
    m_server->m_world.addEntity(other);

    Atlas::Objects::Operation::Talk op;
    op->setFrom(m_creator->getId());
    op->setTo(compose("%1", m_id_counter++));

    m_connection->externalOperation(op, *m_connection);

    // Operation should be via world dispatch, as if it was from the Entity
    // we are puppeting.
    ASSERT_TRUE(m_Link_send_sent.isValid());
    ASSERT_EQUAL(m_Link_send_sent->getParents().front(),
                 "unseen");
    ASSERT_TRUE(!m_Link_send_sent->isDefaultTo());
    ASSERT_EQUAL(m_Link_send_sent->getTo(), m_creator->getId());
}
TestAccount::TestAccount(ServerRouting & svr, long id, long cid) :
          Account(new Connection(*(CommSocket*)0,
                                 svr,
                                 "7546215f-ac75-4e1a-a2c3-a9226219259b",
                                 compose("%1", cid),
                                 cid),
                  "cec7a6f5-ebf1-4531-a0d9-ed9bb46882ad",
                  "59cf380e-7398-48a7-81cc-961265fadcd0",
                  compose("%1", cid),
                  cid)
{
}
Example #5
0
void TrustedConnectionCreatorintegration::test_external_op_puppet()
{
    // Dispatching a Talk external op from the creator, to the creator should
    // result in it being passed directly to the normal op dispatch,
    // shortcutting the world.

    m_creator->m_externalMind = new ExternalMind(*m_creator);
    m_creator->m_externalMind->linkUp(m_connection);

    Entity * other = new Entity(compose("%1", m_id_counter), m_id_counter++);
    other->setType(m_creatorType);
    m_server->m_world.addEntity(other);

    Atlas::Objects::Operation::Talk op;
    op->setFrom(m_creator->getId());
    op->setTo(other->getId());

    m_connection->externalOperation(op, *m_connection);

    // Operation should be via world dispatch, as if it was from the Entity
    // we are puppeting.
    ASSERT_TRUE(m_BaseWorld_message_called.isValid());
    ASSERT_EQUAL(m_BaseWorld_message_called->getClassNo(),
                 Atlas::Objects::Operation::TALK_NO);
    ASSERT_TRUE(!m_BaseWorld_message_called->isDefaultTo());
    ASSERT_EQUAL(m_BaseWorld_message_called->getTo(), other->getId());
    ASSERT_NOT_NULL(m_BaseWorld_message_called_from);
    ASSERT_EQUAL(m_BaseWorld_message_called_from, other);
}
Example #6
0
void Admin::createObject(const std::string & type_str,
                           const Root & arg,
                           const Operation & op,
                           OpVector & res)
{
    const std::string & objtype = arg->getObjtype();
    if (objtype == "class" || objtype == "op_definition") {
        // New entity type
        if (!arg->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
            error(op, "Set arg has no id.", res, getId());
            return;
        }
        const std::string & id = arg->getId();

        if (Inheritance::instance().hasClass(id)) {
            error(op, "Attempt to install type that already exists", res,
                  getId());
            return;
        }
        const Root & o = Inheritance::instance().getClass(type_str);
        if (!o.isValid()) {
            error(op, compose("Attempt to install type with non-existant "
                              "parent \"%1\"", type_str), res, getId());
            return;
        }
        if (Ruleset::instance()->installRule(id, "unknown", arg) == 0) {
            Info info;
            info->setTo(getId());
            info->setArgs1(arg);
            res.push_back(info);
        } else {
            error(op, "Installing new type failed", res, getId());
        }
    } else if (type_str == "juncture") {
        std::string junc_id;
        long junc_iid = newId(junc_id);
        if (junc_iid < 0) {
            error(op, "Juncture failed as no ID available", res, getId());
            return;
        }

        Juncture * j = new Juncture(m_connection, junc_id, junc_iid);

        m_connection->addObject(j);
        m_connection->m_server.addObject(j);

        Anonymous info_arg;
        j->addToEntity(info_arg);

        Info info;
        info->setTo(getId());
        info->setArgs1(info_arg);
        if (!op->isDefaultSerialno()) {
            info->setRefno(op->getSerialno());
        }
        res.push_back(info);
    } else {
        Account::createObject(type_str, arg, op, res);
    }
}
Example #7
0
void Admintest::test_SetOperation_obj_IG()
{
    Account_SetOperation_called = 0;

    long cid = m_id_counter++;
    Entity * c = new Entity(compose("%1", cid), cid);

    m_account->m_charactersDict.insert(std::make_pair(cid, c));

    Atlas::Objects::Operation::Set op;
    OpVector res;

    Anonymous arg;
    arg->setObjtype("obj");
    arg->setId(c->getId());
    op->setArgs1(arg);

    m_account->SetOperation(op, res);

    ASSERT_EQUAL(Account_SetOperation_called, m_account);

    // The operation returned would have come from Account::SetOperation
    // but that is stubbed out
    ASSERT_EQUAL(res.size(), 0u);

    delete c;
}
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;
}
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;
}
Example #10
0
/// \brief Create a new account on the server
///
/// @param name User name of the new account
/// @param password Password of the new account
Root BaseClient::createSystemAccount()
{
    Anonymous player_ent;
    player_ent->setAttr("username", create_session_username());
    player_ent->setAttr("password", compose("%1%2", ::rand(), ::rand()));
    player_ent->setParents(std::list<std::string>(1, "sys"));
    
    Create createAccountOp;
    createAccountOp->setArgs1(player_ent);
    createAccountOp->setSerialno(m_connection.newSerialNo());
    send(createAccountOp);
    if (m_connection.wait() != 0) {
        std::cerr << "ERROR: Failed to log into server: \""
                  << m_connection.errorMessage() << "\""
                  << std::endl << std::flush;
        return Root(0);
    }

    const Root & ent = m_connection.getInfoReply();

    if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
        std::cerr << "ERROR: Logged in, but account has no id" << std::endl
                  << std::flush;
    } else {
        m_playerId = ent->getId();
        // m_playerName = name;
    }

    return ent;
}
Example #11
0
void StorageManager::restoreThoughts(LocatedEntity * ent)
{
    Database * db = Database::instance();
    const DatabaseResult res = db->selectThoughts(ent->getId());
    Atlas::Message::ListType thoughts_data;

    DatabaseResult::const_iterator I = res.begin();
    DatabaseResult::const_iterator Iend = res.end();
    for (; I != Iend; ++I) {
        const std::string thought = I.column("thought");
        if (thought.empty()) {
            log(ERROR,
                    compose("No thought column in property row for %1",
                            ent->getId()));
            continue;
        }
        MapType thought_data;
        db->decodeMessage(thought, thought_data);
        thoughts_data.push_back(thought_data);
    }

    if (!thoughts_data.empty()) {
        OpVector opRes;

        Atlas::Objects::Operation::Think thoughtOp;
        Atlas::Objects::Operation::Set setOp;
        setOp->setArgsAsList(thoughts_data);
        //Make the thought come from the entity itself
        thoughtOp->setArgs1(setOp);
        thoughtOp->setTo(ent->getId());
        thoughtOp->setFrom(ent->getId());

        ent->sendWorld(thoughtOp);
    }
}
Example #12
0
void SystemAccounttest::setup()
{
    Entity * gw = new Entity(compose("%1", m_id_counter),
                             m_id_counter++);
    m_server = new ServerRouting(*new TestWorld(*gw),
                                 "5529d7a4-0158-4dc1-b4a5-b5f260cac635",
                                 "bad621d4-616d-4faf-b9e6-471d12b139a9",
                                 compose("%1", m_id_counter), m_id_counter++,
                                 compose("%1", m_id_counter), m_id_counter++);
    m_connection = new Connection(*(CommSocket*)0, *m_server,
                                  "8d18a4e8-f14f-4a46-997e-ada120d5438f",
                                  compose("%1", m_id_counter), m_id_counter++);
    m_account = new SystemAccount(m_connection,
                                  "6c9f3236-5de7-4ba4-8b7a-b0222df0af38",
                                  "fa1a03a2-a745-4033-85cb-bb694e921e62",
                                  compose("%1", m_id_counter), m_id_counter++);
}
Example #13
0
DatabasePostgres::~DatabasePostgres()
{
    if (!pendingQueries.empty()) {
        log(ERROR, compose("Database delete with %1 queries pending",
                           pendingQueries.size()));

    }
    shutdownConnection();
}
void AccountServerLobbyintegration::setup()
{
    LocatedEntity * gw = new Entity(compose("%1", m_id_counter),
                                    m_id_counter++);
    m_server = new ServerRouting(*new TestWorld(*gw),
                                 "59331d74-bb5d-4a54-b1c2-860999a4e344",
                                 "93e1f67f-63c5-4b07-af4c-574b2273563d",
                                 compose("%1", m_id_counter), m_id_counter++,
                                 compose("%1", m_id_counter), m_id_counter++);
    for (int i = 0; i < 3; ++i) {
        m_account = new TestAccount(*m_server,
                                    m_id_counter++,
                                    m_id_counter++);
        m_server->addAccount(m_account);
        m_server->m_lobby.addAccount(m_account);
    }
    ASSERT_NOT_NULL(m_account);
}
Example #15
0
int DatabasePostgres::connect(const std::string& context, std::string& error_msg)
{
    std::stringstream conninfos;

    std::string db_server;
    if (readConfigItem(context, "dbserver", db_server) == 0) {
        if (db_server.empty()) {
            log(WARNING, "Empty database hostname specified in config file. "
                         "Using none.");
        } else {
            conninfos << "host=" << db_server << " ";
        }
    }

    std::string dbname;
    if (context == CYPHESIS) {
        dbname = CYPHESIS;
    } else {
        dbname = compose("%1_%2", CYPHESIS, ::instance);
    }
    readConfigItem(context, "dbname", dbname);
    conninfos << "dbname=" << dbname << " ";

    std::string db_user;
    if (readConfigItem(context, "dbuser", db_user) == 0) {
        if (db_user.empty()) {
            log(WARNING, "Empty username specified in config file. "
                         "Using current user.");
        } else {
            conninfos << "user="******" ";
        }
    }

    std::string db_passwd;
    if (readConfigItem(context, "dbpasswd", db_passwd) == 0) {
        conninfos << "password="******" ";
    }

    const std::string cinfo = conninfos.str();

    m_connection = PQconnectdb(cinfo.c_str());

    if (m_connection == nullptr) {
        error_msg = "Unknown error";
        return -1;
    }

    if (PQstatus(m_connection) != CONNECTION_OK) {
        error_msg = PQerrorMessage(m_connection);
        PQfinish(m_connection);
        m_connection = nullptr;
        return -1;
    }

    return 0;
}
Example #16
0
void StorageManager::restoreChildren(LocatedEntity * parent)
{
    Database * db = Database::instance();
    DatabaseResult res = db->selectEntities(parent->getId());
    EntityBuilder * eb = EntityBuilder::instance();

    // Iterate over res creating entities, and sorting out position, location
    // and orientation. Restore children, but don't restore any properties yet.
    DatabaseResult::const_iterator I = res.begin();
    DatabaseResult::const_iterator Iend = res.end();
    for (; I != Iend; ++I) {
        const std::string id = I.column("id");
        const int int_id = forceIntegerId(id);
        const std::string type = I.column("type");
        //By sending an empty attributes pointer we're telling the builder not to apply any default
        //attributes. We will instead apply all attributes ourselves when we later on restore attributes.
        Atlas::Objects::SmartPtr<Atlas::Objects::Entity::RootEntityData> attrs(nullptr);
        LocatedEntity * child = eb->newEntity(id, int_id, type, attrs, BaseWorld::instance());
        if (!child) {
            log(ERROR, compose("Could not restore entity with id %1 of type %2"
                    ", most likely caused by this type missing.",
                    id, type));
            continue;
        }
        
        const std::string location_string = I.column("location");
        MapType loc_data;
        db->decodeMessage(location_string, loc_data);
        child->m_location.readFromMessage(loc_data);
        if (!child->m_location.pos().isValid()) {
            std::cout << "No pos data" << std::endl << std::flush;
            log(ERROR, compose("Entity %1 restored from database has no "
                               "POS data. Ignored.", child->getId()));
            delete child;
            continue;
        }
        child->m_location.m_loc = parent;
        child->setFlags(entity_clean | entity_pos_clean | entity_orient_clean);
        BaseWorld::instance().addEntity(child);
        restoreChildren(child);
    }
}
Example #17
0
int RuleHandler::getScriptDetails(const Atlas::Message::MapType & script,
                                  const std::string & class_name,
                                  const std::string & context,
                                  std::string & script_package,
                                  std::string & script_class)
{
    MapType::const_iterator J = script.find("name");
    MapType::const_iterator Jend = script.end();

    if (J == Jend || !J->second.isString()) {
        log(ERROR, compose("%1 \"%2\" script has no name.",
                           context, class_name));
        return -1;
    }
    const std::string & script_name = J->second.String();
    J = script.find("language");
    if (J == Jend || !J->second.isString()) {
        log(ERROR, compose("%1 \"%2\" script has no language.",
                           context, class_name));
        return -1;
    }
    const std::string & script_language = J->second.String();
    if (script_language != "python") {
        log(ERROR, compose("%1 \"%2\" script has unknown language \"%3\".",
                           context, class_name, script_language));
        return -1;
    }
    std::string::size_type ptr = script_name.rfind(".");
    if (ptr == std::string::npos) {
        log(ERROR, compose("%1 \"%2\" python script has bad class name \"%3\".",
                           context, class_name, script_name));
        return -1;
    }
    script_package = script_name.substr(0, ptr);
    script_class = script_name.substr(ptr + 1);

    return 0;
}
void ServerAccounttest::test_addNewEntity_success()
{
    long cid = m_id_counter++;
    Entity * c = new Character(compose("%1", cid), cid);
    TestWorld_addNewEntity_ret_value = c;

    std::string type_str("unimportant_string");
    RootEntity arg;

    LocatedEntity * e = m_account->addNewEntity(type_str, arg, arg);

    ASSERT_EQUAL(c, e);

    delete TestWorld_addNewEntity_ret_value;
    TestWorld_addNewEntity_ret_value = 0;
}
Example #19
0
bool Motion::resolveCollision()
{
    Location & location(m_entity.m_location);
    bool moving = true;

    assert(m_collision);
    assert(m_collEntity != 0);
    assert(m_collEntity->m_location.m_loc != 0);

    // We have arrived at our target position and must
    // stop, or be deflected

    // FIXME This should become an assertion.
    if (location.m_loc != m_collEntity->m_location.m_loc) {
        // Race condition
        // This occurs if we get asked for a new update before
        // the last move has taken effect, so we make the new
        // pos exactly as it was when the last collision was
        // predicted.
        log(ERROR, compose("Collision Error: %1(%2) with parent %3 "
                           "colliding with %4(%5) with parent %6",
                           m_entity.getId(), m_entity.getType()->name(),
                           location.m_loc->getId(), m_collEntity->getId(),
                           m_collEntity->getType()->name(),
                           m_collEntity->m_location.m_loc->getId()));
    } else {
        // FIXME Generate touch ops
        // This code relies on m_collNormal being a unit vector
        float vel_square_mag = location.velocity().sqrMag();
        location.m_velocity -= m_collNormal * Dot(m_collNormal, location.m_velocity);
        if (location.m_velocity.mag() / consts::base_velocity > 0.05) {
            m_collEntity = NULL;
            location.m_velocity.normalize();
            location.m_velocity *= std::sqrt(vel_square_mag);
        } else {
            // reset();
            location.m_velocity = Vector3D(0,0,0);
            moving = false;
        }
    }

    clearCollision();
    return moving;
}
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;
}
Example #21
0
void Admintest::test_SetOperation_obj_not_found()
{
    Account_SetOperation_called = 0;

    long cid = m_id_counter++;

    Atlas::Objects::Operation::Set op;
    OpVector res;

    Anonymous arg;
    arg->setObjtype("obj");
    arg->setId(compose("%1", cid));
    op->setArgs1(arg);

    m_account->SetOperation(op, res);

    ASSERT_NULL(Account_SetOperation_called);

    // FIXME No error? Is that right?
    ASSERT_EQUAL(res.size(), 0u);
}
Example #22
0
        return;
    }
    const std::string & hostname = hostname_attr.String();

    Element port_attr;
    if (arg->copyAttr("port", port_attr) != 0 || !port_attr.isInt()) {
        error(op, "Argument to connect op has no port", res, getId());
        return;
    }
    int port = port_attr.Int();

    debug(std::cout << "Connecting to " << hostname << std::endl << std::flush;);
    m_address = new PeerAddress;

    boost::asio::ip::tcp::resolver resolver(m_connection->m_commSocket.m_io_service);
    boost::asio::ip::tcp::resolver::query query(hostname, compose("%1", port));

    try {
        m_address->i = resolver.resolve(query);
    } catch (const std::exception& e) {
        error(op, "Could not connect to peer host.", res, getId());
        return;
    }

    m_connectRef = op->getSerialno();

    if (attemptConnect(hostname, port) != 0) {
        error(op, "Connection failed", res, getId());
    }
}
Example #23
0
int OpRuleHandler::installOpDefinition(const std::string & class_name,
                                       const std::string & parent,
                                       const Atlas::Objects::Root & class_desc,
                                       std::string & dependent,
                                       std::string & reason)
{
    assert(class_name == class_desc->getId());

    Inheritance & i = Inheritance::instance();

    if (!i.hasClass(parent)) {
        debug(std::cout << "op_definition \"" << class_name
                        << "\" has non existant parent \"" << parent
                        << "\". Waiting." << std::endl << std::flush;);
        dependent = parent;
        reason = compose("Operation \"%1\" has parent \"%2\" which does "
                         "not exist.", class_name, parent);
        return 1;
    }

    Atlas::Objects::Root r = atlasOpDefinition(class_name, parent);

    if (i.addChild(class_desc) == 0) {
        return -1;
    }

    Atlas::Objects::Factories::instance()->addFactory(class_name, &Atlas::Objects::generic_factory);

    return 0;
}

int OpRuleHandler::modifyOpDefinition(const std::string & class_name,
Example #24
0
void Admin::GetOperation(const Operation & op, OpVector & res)
{
    const std::vector<Root> & args = op->getArgs();
    if (args.empty()) {
        error(op, "Get has no args.", res, getId());
        return;
    }
    const Root & arg = args.front();
    if (!arg->hasAttrFlag(Atlas::Objects::OBJTYPE_FLAG)) {
        error(op, "Get arg has no objtype.", res, getId());
        return;
    }
    const std::string & objtype = arg->getObjtype();
    if (!arg->hasAttrFlag(Atlas::Objects::ID_FLAG)) {
        error(op, "Get arg has no id.", res, getId());
        return;
    }
    const std::string & id = arg->getId();
    if (id.empty()) {
        error(op, "Get arg id empty", res, getId());
        return;
    }
    Info info;
    if (objtype == "object" || objtype == "obj") {
        if (m_connection == 0) {
            return;
        }
        long intId = integerId(id);

        const RouterMap & OOGDict = m_connection->m_server.getObjects();
        RouterMap::const_iterator J = OOGDict.find(intId);
        const EntityDict & worldDict = m_connection->m_server.m_world.getEntities();
        EntityDict::const_iterator K = worldDict.find(intId);

        if (J != OOGDict.end()) {
            Router * obj = J->second;
            Anonymous info_arg;
            obj->addToEntity(info_arg);
            info->setArgs1(info_arg);
        } else if (K != worldDict.end()) {
            Anonymous info_arg;
            K->second->addToEntity(info_arg);
            info->setArgs1(info_arg);
        } else {
            clientError(op, compose("Unknown object id \"%1\" requested", id),
                        res, getId());
            return;
        }
    } else if (objtype == "class" ||
               objtype == "meta" ||
               objtype == "op_definition") {
        const Root & o = Inheritance::instance().getClass(id);
        if (!o.isValid()) {
            clientError(op, compose("Unknown type definition for \"%1\" "
                                    "requested", id), res);
            return;
        }
        info->setArgs1(o);
    } else if (objtype == "op") {
        if (arg->getClassNo() == Atlas::Objects::Operation::THOUGHT_NO) {
            long intId = integerId(id);
            const EntityDict & worldDict = m_connection->m_server.m_world.getEntities();
            EntityDict::const_iterator K = worldDict.find(intId);

            if (K != worldDict.end()) {
                Character* character = dynamic_cast<Character*>(K->second);
                if (character) {
                    character->sendMind(op, res);
                } else {
                    clientError(op, compose("Entity with id \"%1\" is not a character", id),
                                res, getId());
                    return;
                }

                std::vector<Root> newRet;
                //Why can't I do "info->setArgs(res)"?
                for (auto& operation : res) {
                    newRet.push_back(operation);
                }
                info->setArgs(newRet);
                res.clear();
            } else {
                clientError(op, compose("Unknown object id \"%1\" requested", id),
                            res, getId());
                return;
            }
        } else if (arg->getClassNo() == Atlas::Objects::Operation::GOAL_INFO_NO) {
            long intId = integerId(id);
            const EntityDict & worldDict = m_connection->m_server.m_world.getEntities();
            EntityDict::const_iterator K = worldDict.find(intId);

            if (K != worldDict.end()) {
                Character* character = dynamic_cast<Character*>(K->second);
                if (character) {
                    character->sendMind(op, res);
                } else {
                    clientError(op, compose("Entity with id \"%1\" is not a character", id),
                                res, getId());
                    return;
                }

                std::vector<Root> newRet;
                //Why can't I do "info->setArgs(res)"?
                for (auto& operation : res) {
                    newRet.push_back(operation);
                }
                info->setArgs(newRet);
                res.clear();
            } else {
                clientError(op, compose("Unknown object id \"%1\" requested", id),
                            res, getId());
                return;
            }
        }
    } else {
        error(op, compose("Unknown object type \"%1\" requested for \"%2\"",
                          objtype, id), res, getId());
        return;
    }
    res.push_back(info);
}
Example #25
0
void StorageManager::restorePropertiesRecursively(LocatedEntity * ent)
{
    Database * db = Database::instance();
    PropertyManager * pm = PropertyManager::instance();
    DatabaseResult res = db->selectProperties(ent->getId());

    //Keep track of those properties that have been set on the instance, so we'll know what
    //type properties we should ignore.
    std::unordered_set<std::string> instanceProperties;

    DatabaseResult::const_iterator I = res.begin();
    DatabaseResult::const_iterator Iend = res.end();
    for (; I != Iend; ++I) {
        const std::string name = I.column("name");
        if (name.empty()) {
            log(ERROR, compose("No name column in property row for %1",
                               ent->getId()));
            continue;
        }
        const std::string val_string = I.column("value");
        if (name.empty()) {
            log(ERROR, compose("No value column in property row for %1,%2",
                               ent->getId(), name));
            continue;
        }
        MapType prop_data;
        db->decodeMessage(val_string, prop_data);
        MapType::const_iterator J = prop_data.find("val");
        if (J == prop_data.end()) {
            log(ERROR, compose("No property value data for %1:%2",
                               ent->getId(), name));
            continue;
        }
        assert(ent->getType() != 0);
        const Element & val = J->second;

        Element existingVal;
        if (ent->getAttr(name, existingVal) == 0) {
            if (existingVal == val) {
                //If the existing property, either on the instance or the type, is equal to the persisted one just skip it.
                continue;
            }
        }


        PropertyBase * prop = ent->modProperty(name);
        if (prop == nullptr) {
            prop = pm->addProperty(name, val.getType());
            prop->install(ent, name);
            //This transfers ownership of the property to the entity.
            ent->setProperty(name, prop);
        }

        //If we get to here the property either doesn't exists, or have a different value than the default or existing property.
        prop->set(val);
        prop->setFlags(per_clean | per_seen);
        prop->apply(ent);
        instanceProperties.insert(name);
    }

    if (ent->getType()) {
        for (auto& propIter : ent->getType()->defaults()) {
            if (!instanceProperties.count(propIter.first)) {
                PropertyBase * prop = propIter.second;
                // If a property is in the class it won't have been installed
                // as setAttr() checks
                prop->install(ent, propIter.first);
                // The property will have been applied if it has an overriden
                // value, so we only apply it the value is still default.
                prop->apply(ent);
            }
        }
    }


    //Now restore all properties of the child entities.
    if (ent->m_contains) {
        for (auto& childEntity : *ent->m_contains) {
            restorePropertiesRecursively(childEntity);
        }
    }

    //We must send a sight op to the entity informing it of itself before we send any thoughts.
    //Else the mind won't have any information about itself.
    {
        Atlas::Objects::Operation::Sight sight;
        sight->setTo(ent->getId());
        Atlas::Objects::Entity::Anonymous args;
        ent->addToEntity(args);
        sight->setArgs1(args);
        ent->sendWorld(sight);
    }
    //We should also send a sight op to the parent entity which owns the entity.
    //TODO: should this really be necessary or should we rely on other Sight functionality?
    if (ent->m_location.m_loc) {
        Atlas::Objects::Operation::Sight sight;
        sight->setTo(ent->m_location.m_loc->getId());
        Atlas::Objects::Entity::Anonymous args;
        ent->addToEntity(args);
        sight->setArgs1(args);
        ent->m_location.m_loc->sendWorld(sight);
    }

    restoreThoughts(ent);

}
Example #26
0
void SpawnerProperty::createNewEntity(LocatedEntity * e, const Operation & op,
        OpVector & res, const std::string& locId)
{
    Anonymous create_arg;
    if (!m_entity.empty()) {
        create_arg = smart_dynamic_cast<Anonymous>(
                Factories::instance()->createObject(m_entity));
        if (!create_arg.isValid()) {
            log(ERROR,
                    "Could not parse 'entity' data on spawner into Entity instance.");
            return;
        }
    } else {
        create_arg->setParents(std::list<std::string>(1, m_type));
    }
    create_arg->setLoc(locId);

    WFMath::MTRand& rand = WFMath::MTRand::instance;
    if (m_mode_external) {
        if (!e->m_location.pos().isValid()) {
            log(ERROR,
                    "Tried to spawn entity for which parent has no valid position.");
            return;
        }
        //randomize position and rotation
        float angle = rand.randf(WFMath::numeric_constants<float>::pi() * 2);
        //place it between 0 and 2 meters away
        float distance = rand.randf(2.0f);
        //if we're solid we should make sure it's not within our own radius
        if (e->m_location.isSolid() && e->m_location.bBox().isValid()) {
            distance += e->m_location.radius();
        }
        //and finally make sure that it's not beyond the radius for checking
        if (m_radius != 0.0f) {
            distance = std::min(m_radius, distance);
        }

        float x = (distance * std::cos(angle));
        float y = (distance * std::sin(angle));

        ::addToEntity(
                WFMath::Point<3>(e->m_location.pos()).shift(
                        WFMath::Vector<3>(x, y, 0)), create_arg->modifyPos());
    } else {
        //If it's an internal spawner, spawn anywhere within the bounding box.
        const BBox bbox = e->m_location.m_bBox;
        if (bbox.isValid()) {
            float x = rand.rand(bbox.highCorner().x() - bbox.lowCorner().x())
                    + bbox.lowCorner().x();
            float y = rand.rand(bbox.highCorner().y() - bbox.lowCorner().y())
                    + bbox.lowCorner().y();
            ::addToEntity(WFMath::Point<3>(x, y, 0), create_arg->modifyPos());
        } else {
            ::addToEntity(WFMath::Point<3>::ZERO(), create_arg->modifyPos());
        }
    }
    float rotation = rand.randf(WFMath::numeric_constants<float>::pi() * 2);
    WFMath::Quaternion orientation(WFMath::Vector<3>(0, 0, 1), rotation);
    create_arg->setAttr("orientation", orientation.toAtlas());

    Create create;
    create->setTo(e->m_location.m_loc->getId());
    create->setArgs1(create_arg);
    res.push_back(create);

    debug(log(NOTICE, compose("Spawner belonging to entity %1 creating new"
            " entity of type %2", e->getId(), m_type))
    ;);
Example #27
0
        const std::string & parent, const Root & class_desc,
        std::string & dependent, std::string & reason)
{
    assert(class_name == class_desc->getId());

    // Get the new factory for this rule
    ArchetypeFactory * parent_factory =
            dynamic_cast<ArchetypeFactory*>(m_builder->getClassFactory(parent));
    if (parent_factory == 0) {
        debug(
                std::cout << "class \"" << class_name
                        << "\" has non existant parent \"" << parent
                        << "\". Waiting." << std::endl << std::flush
                ;);
        dependent = parent;
        reason = compose("Entity rule \"%1\" has parent \"%2\" which does "
                "not exist.", class_name, parent);
        return 1;
    }
    ArchetypeFactory * factory = parent_factory->duplicateFactory();
    if (factory == 0) {
        log(ERROR,
                compose(
                        "Attempt to install rule \"%1\" which has parent \"%2\" "
                                "which cannot be instantiated", class_name,
                        parent));
        return -1;
    }

    assert(factory->m_parent == parent_factory);

    if (populateArchetypeFactory(class_name, factory, class_desc->asMessage(),