void View::create(const RootEntity& gent) { std::string eid(gent->getId()); if (m_contents.count(eid)) { // already known locally, just emit the signal EntityCreated.emit( m_contents[eid] ); return; } bool alreadyAppeared = false; PendingSightMap::iterator pending = m_pending.find(eid); if (pending != m_pending.end()) { // already being retrieved, but we have the data now alreadyAppeared = (pending->second == SACTION_QUEUED) || (pending->second == SACTION_APPEAR); pending->second = SACTION_DISCARD; // when the SIGHT turns up } Entity* ent = createEntity(gent); m_contents[eid] = ent; ent->init(gent, true); if (gent->isDefaultLoc()) setTopLevelEntity(ent); InitialSightEntity.emit(ent); // depends on relative order that sight(create) and appear are received in if (alreadyAppeared) { ent->setVisible(true); EntityCreated.emit(ent); } }
/// \brief Copy attributes into an Atlas entity /// /// @param ent Atlas entity this entity should be copied into void Entity::addToEntity(const RootEntity & ent) const { // We need to have a list of keys to pull from attributes. PropertyDict::const_iterator J; PropertyDict::const_iterator Jend; if (m_type != 0) { J = m_type->defaults().begin(); Jend = m_type->defaults().end(); for (; J != Jend; ++J) { J->second->add(J->first, ent); } } J = m_properties.begin(); Jend = m_properties.end(); for (; J != Jend; ++J) { J->second->add(J->first, ent); } ent->setStamp(m_seq); if (m_type != 0) { ent->setParents(std::list<std::string>(1, m_type->name())); } m_location.addToEntity(ent); ent->setObjtype("obj"); }
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); }
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(); }
void View::sight(const RootEntity& gent) { bool visible = true; std::string eid = gent->getId(); PendingSightMap::iterator pending = m_pending.find(eid); // examine the pending map, to see what we should do with this entity if (pending != m_pending.end()) { switch (pending->second) { case SACTION_APPEAR: visible = true; break; case SACTION_DISCARD: m_pending.erase(pending); issueQueuedLook(); return; case SACTION_HIDE: visible = false; break; case SACTION_QUEUED: error() << "got sight of queued entity " << eid << " somehow"; eraseFromLookQueue(eid); break; default: throw InvalidOperation("got bad pending action for entity"); } m_pending.erase(pending); } // if we got this far, go ahead and build / update it Entity *ent = getEntity(eid); if (ent) { // existing entity, update in place ent->sight(gent); } else { ent = initialSight(gent); EntitySeen.emit(ent); } if (gent->isDefaultLoc()) { // new top level entity setTopLevelEntity(ent); } ent->setVisible(visible); issueQueuedLook(); }
void ClientConnection::processOOGLook(const Look& lk) { const std::vector<Root>& args = lk->getArgs(); std::string lookTarget; if (args.empty()) { lookTarget = "_lobby"; } else { lookTarget = args.front()->getId(); } RootEntity thing; if (m_server->m_accounts.count(lookTarget)) { thing = m_server->m_accounts[lookTarget]; if (lookTarget != lk->getFrom()) { // prune thing->removeAttr("characters"); thing->removeAttr("password"); } } else if (m_server->m_world.count(lookTarget)) { // ensure it's owned by the account, i.e in characters if (!entityIsCharacter(lookTarget)) { sendError("not allowed to look at that entity", lk); return; } thing = m_server->m_world[lookTarget]; } else if (m_server->m_rooms.count(lookTarget)) { // should check room view permissions? thing = m_server->m_rooms[lookTarget]; } else { // didn't find any entity with the id sendError("processed OOG look for unknown entity " + lookTarget, lk); return; } Sight st; st->setArgs1(thing); st->setFrom(lookTarget); st->setTo(lk->getFrom()); st->setRefno(lk->getSerialno()); send(st); }
void Property<IdList>::add(const std::string & s, const RootEntity & ent) const { if (!m_data.empty()) { ListType list; idListasObject(m_data, list); ent->setAttr(s, list); } }
void ClientConnection::processAnonymousGet(const Get& get) { const std::vector<Root>& args = get->getArgs(); if (args.empty()) { Info serverInfo; RootEntity svObj; Atlas::Message::ListType prs; prs.push_back("server"); svObj->setParentsAsList(prs); svObj->setName("Bob's StubServer"); svObj->setAttr("server", "stubserver"); svObj->setAttr("ruleset", "stub-world"); svObj->setAttr("uptime", 666.0); svObj->setAttr("clients", 42); serverInfo->setArgs1(svObj); send(serverInfo); } else { std::string typeName = args.front()->getId(); if (m_server->m_types.count(typeName)) { Info typeInfo; typeInfo->setArgs1(m_server->m_types[typeName]); typeInfo->setRefno(get->getSerialno()); send(typeInfo); } else sendError("unknown type " + typeName, get); } }
void ServerInfo::processServer(const RootEntity &svr) { Atlas::Message::Element element; if (!svr->copyAttr("ruleset", element) && element.isString()) { _ruleset = element.String(); } else { return; } _name = svr->getName(); if (!svr->copyAttr("clients", element) && element.isInt()) { _clients = (int)element.Int(); } else { return; } if (!svr->copyAttr("server", element) && element.isString()) { _server = element.String(); } else { return; } if (!svr->copyAttr("uptime", element) && element.isFloat()) { _uptime = element.Float(); } else { return; } m_status = VALID; if (!svr->copyAttr("entities", element) && element.isInt()) { _entities = element.Int(); } if (!svr->copyAttr("version", element) && element.isString()) { m_version = element.String(); } if (!svr->copyAttr("builddate", element) && element.isString()) { m_buildDate = element.String(); } if (!svr->copyAttr("assets", element) && element.isList()) { for (auto& url : element.List()) { if (url.isString()) { m_assets.emplace_back(url.String()); } } } }
void ServerAccount::createObject(const std::string & type_str, const Root & arg, const Operation & op, OpVector & res) { // Format of the Create ops that are received by this function should // have the entity to be created as the first argument. If the entity // being created is a character associated with an account, an additional // argument should specify the possess key that will be used by the client // to claim ownership of the entity being created. if (arg->getObjtype() != "obj") { // Return error to peer error(op, "Only creation of entities by peer server is permitted", res, getId()); return; } RootEntity ent = smart_dynamic_cast<RootEntity>(arg); if(!ent.isValid()) { log(ERROR, "Character creation arg is malformed"); return; } // If we have a possess key (entity has a mind) TeleportAuthenticator * tele_auth = 0; std::string possess_key; const std::vector<Root> & args = op->getArgs(); if (args.size() == 2) { const Root & arg2 = args.back(); Element key; if(arg2->copyAttr("possess_key", key) == 0 && key.isString()) { possess_key = key.String(); tele_auth = TeleportAuthenticator::instance(); } else { log(ERROR, "Entity has mind but no possess key found"); return; } } debug( std::cout << "ServerAccount creating a " << type_str << " object" << std::endl << std::flush; );
void EntityImporterBase::createEntity(const RootEntity & obj, OpVector & res) { ++mStats.entitiesProcessedCount; ++mStats.entitiesCreateCount; EventProgress.emit(); m_state = ENTITY_CREATING; assert(mTreeStack.size() > 1); std::deque<StackEntry>::reverse_iterator I = mTreeStack.rbegin(); ++I; assert(I != mTreeStack.rend()); const std::string & loc = I->restored_id; RootEntity create_arg = obj.copy(); create_arg->removeAttrFlag(Atlas::Objects::Entity::CONTAINS_FLAG); create_arg->removeAttrFlag(Atlas::Objects::Entity::VELOCITY_FLAG); create_arg->removeAttrFlag(Atlas::Objects::ID_FLAG); create_arg->setLoc(loc); //Remove any attribute which references another entity from the Create op. //This is because the attribute will at this time with certainty refer to the wrong or a non-existing entity. //The attribute will later on be set through a Set op in sendResolvedEntityReferences(). auto referenceMapEntryI = mEntitiesWithReferenceAttributes.find(obj->getId()); if (referenceMapEntryI != mEntitiesWithReferenceAttributes.end()) { for (const auto& attributeName : referenceMapEntryI->second) { create_arg->removeAttr(attributeName); } } Create create; create->setArgs1(create_arg); create->setFrom(mAvatarId); create->setSerialno(newSerialNumber()); mCreateEntityMapping.insert(std::make_pair(create->getSerialno(), obj->getId())); res.push_back(create); }
LocatedEntity * CreatorClient::handleMakeResponse(const RootOperation & op, double create_time) { if (op->getArgs().empty()) { std::cerr << "Arg of reply to make has no args" << std::endl << std::flush; return NULL; } RootEntity created = smart_dynamic_cast<RootEntity>(op->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, create_time); return obj; }
void Interactive::disappearanceArrived(const Operation & op) { if (m_accountId.empty()) { return; } if (m_accountId != op->getTo()) { // This is an IG op we are monitoring return; } if (op->getArgs().empty()) { return; } RootEntity ent = smart_dynamic_cast<RootEntity>(op->getArgs().front()); if (!ent.isValid()) { std::cerr << "Got Disappearance of non-entity" << std::endl << std::flush; return; } if (!ent->hasAttrFlag(Atlas::Objects::ID_FLAG)) { std::cerr << "Got Disappearance of non-string ID" << std::endl << std::flush; return; } const std::string & id = ent->getId(); std::cout << "Disappearance(id: " << id << ")"; if (!ent->hasAttrFlag(Atlas::Objects::Entity::LOC_FLAG)) { std::cout << std::endl << std::flush; return; } const std::string & loc = ent->getLoc(); std::cout << " in " << loc << std::endl; if (loc == "lobby") { std::cout << id << " has logged out." << std::endl; } std::cout << std::flush; }
void EntityImporterBase::sendResolvedEntityReferences() { if (!mEntitiesWithReferenceAttributes.empty()) { for (auto entryI : mEntitiesWithReferenceAttributes) { const auto& persistedEntityId = entryI.first; const auto& referenceEntries = entryI.second; auto createdEntityI = mEntityIdMap.find(persistedEntityId); if (createdEntityI == mEntityIdMap.end()) { S_LOG_WARNING("Could not find final server side entity id for persisted entity " << persistedEntityId << " when doing entity ref resolving."); continue; } const auto& createdEntityId = createdEntityI->second; //This should not fail at this phase, so we're not doing any checks. auto& persistedEntity = mPersistedEntities.find(persistedEntityId)->second; RootEntity entity; for (const auto& referenceEntry : referenceEntries) { Element element = persistedEntity->getAttr(referenceEntry.propertyName); resolveEntityReferences(element); entity->setAttr(referenceEntry.propertyName, element); } Set set; set->setFrom(mAvatarId); set->setSerialno(newSerialNumber()); set->setTo(createdEntityId); set->setArgs1(entity); mSetOpsInTransit++; sigc::slot<void, const Operation&> slot = sigc::mem_fun(*this, &EntityImporterBase::operationSetResult); sendAndAwaitResponse(set, slot); } } else { sendMinds(); } }
HandlerResult TerrainModProperty::move_handler(LocatedEntity * e, const Operation & op, OpVector & res) { // FIXME Force instantiation of a class property? // Check the validity of the operation. const std::vector<Root> & args = op->getArgs(); if (args.empty()) { return OPERATION_IGNORED; } RootEntity ent = Atlas::Objects::smart_dynamic_cast<RootEntity>(args.front()); if (!ent.isValid()) { return OPERATION_IGNORED; } if (e->getId() != ent->getId()) { return OPERATION_IGNORED; } // Update the modifier move(e); return OPERATION_IGNORED; }
void ServerInfo::processServer(const RootEntity &svr) { Atlas::Message::Element element; if (!svr->copyAttr("ruleset", element) && element.isString()) { _ruleset = element.asString(); } else { return; } _name = svr->getName(); if (!svr->copyAttr("clients", element) && element.isInt()) { _clients = element.asInt(); } else { return; } if (!svr->copyAttr("server", element) && element.isString()) { _server = element.asString(); } else { return; } if (!svr->copyAttr("uptime", element) && element.isFloat()) { _uptime = element.asFloat(); } else { return; } m_status = VALID; if (!svr->copyAttr("entities", element) && element.isInt()) { _entities = element.asInt(); } if (!svr->copyAttr("version", element) && element.isString()) { m_version = element.asString(); } if (!svr->copyAttr("builddate", element) && element.isString()) { m_buildDate = element.asString(); } }
Eris::EntityPtr WEFactory::instantiate(const RootEntity & ge, Eris::TypeInfo * type, Eris::View * v) { RenderableEntity * re = 0; const std::string & id = ge->getId(); // Eris::TypeInfoPtr type = v->getConnection()->getTypeService()->getTypeForAtlas(ge); sigc::slot<void> slot; if (type->isA(autonomousType)) { AutonomousEntity * ae = new AutonomousEntity(id, type, v); slot = sigc::bind<AutonomousEntity *>(AutonomousEntityCreated.make_slot(), ae); re = ae; } else if (type->isA(terrainType)) { TerrainEntity * te = new TerrainEntity(id, type, v); slot = sigc::bind<TerrainEntity *>(TerrainEntityCreated.make_slot(), te); re = te; } else if (type->isA(treeType)) { TreeEntity * te = new TreeEntity(id, type, v); slot = sigc::bind<TreeEntity *>(TreeEntityCreated.make_slot(), te); re = te; } else { re = new RenderableEntity(id, type, v); slot = sigc::bind<RenderableEntity *>(RenderableEntityCreated.make_slot(), re); } if (re->m_drawer == 0) { RendererMap::const_iterator I = m_renderFactories.find(type); if (I != m_renderFactories.end()) { re->m_drawer = I->second->newRenderer(m_renderer, *re); } else { // FIXME Ascend the type tree to try and find a rough match? re->m_drawer = new BBoxRenderer(m_renderer, *re); } } slot(); return re; }
LocatedEntity * CharacterClient::sendLook(const Operation & op) { OpVector result; if (sendAndWaitReply(op, result) != 0) { std::cerr << "No reply to look" << std::endl << std::flush; return NULL; } assert(!result.empty()); const Operation & res = result.front(); if (!res.isValid()) { std::cerr << "NULL reply to look" << std::endl << std::flush; return NULL; } const std::string & resparent = res->getParent(); if (resparent == "unseen") { return NULL; } if (resparent != "sight") { std::cerr << "Reply to look is " << resparent << " not sight" << std::endl << std::flush; return NULL; } if (res->getArgs().empty()) { std::cerr << "Reply to look has no args" << std::endl << std::flush; return NULL; } RootEntity seen = smart_dynamic_cast<RootEntity>(res->getArgs().front()); if (!seen.isValid()) { std::cerr << "Sight arg is not an entity" << std::endl << std::flush; return NULL; } if (!seen->hasAttrFlag(Atlas::Objects::ID_FLAG)) { std::cerr << "Looked at entity has no id" << std::endl << std::flush; return NULL; } const std::string & sight_id = seen->getId(); if (seen->hasAttrFlag(Atlas::Objects::PARENT_FLAG)) { std::cout << "Seen: " << seen->getParent() << "(" << sight_id << ")" << std::endl << std::flush; } else { std::cout << "Seen: " << sight_id << std::endl << std::flush; } LocatedEntity * obj = m_map.updateAdd(seen, res->getSeconds()); return obj; }
void ServerRouting::addToEntity(const RootEntity & ent) const { ent->setObjtype("obj"); ent->setAttr("server", "cyphesis"); ent->setAttr("ruleset", m_svrRuleset); ent->setName(m_svrName); ent->setParents(std::list<std::string>(1, "server")); ent->setAttr("clients", m_numClients); ent->setAttr("uptime", m_world.upTime()); ent->setAttr("builddate", std::string(consts::buildTime)+", "+std::string(consts::buildDate)); ent->setAttr("buildid", consts::buildId); ent->setAttr("version", std::string(consts::version)); if (restricted_flag) { ent->setAttr("restricted", "true"); } ent->setAttr("entities", (long)m_world.getEntities().size()); // We could add all sorts of stats here, but I don't know exactly what yet. }
void EntityImporterBase::createEntity(const RootEntity & obj, OpVector & res) { ++mStats.entitiesProcessedCount; ++mStats.entitiesCreateCount; EventProgress.emit(); m_state = ENTITY_CREATING; assert(mTreeStack.size() > 1); auto I = mTreeStack.rbegin(); ++I; assert(I != mTreeStack.rend()); const std::string & loc = I->restored_id; RootEntity create_arg = obj.copy(); create_arg->removeAttrFlag(Atlas::Objects::Entity::CONTAINS_FLAG); create_arg->removeAttrFlag(Atlas::Objects::Entity::VELOCITY_FLAG); create_arg->removeAttrFlag(Atlas::Objects::ID_FLAG); create_arg->setLoc(loc); //Remove any attribute which references another entity from the Create op. //This is because the attribute will at this time with certainty refer to the wrong or a non-existing entity. //The attribute will later on be set through a Set op in sendResolvedEntityReferences(). auto referenceMapEntryI = mEntitiesWithReferenceAttributes.find(obj->getId()); if (referenceMapEntryI != mEntitiesWithReferenceAttributes.end()) { std::set<std::string> resolvedAttributes; for (const auto& referenceEntry : referenceMapEntryI->second) { size_t resolvedEntitiesCount = 0; //Check if all the referenced entities perhaps already have been created. for (const auto& entityId : referenceEntry.referencedEntities) { auto resolvedI = mEntityIdMap.find(entityId); if (resolvedI != mEntityIdMap.end()) { resolvedEntitiesCount++; } } //If all entities were resolved, we should resolve the property now. if (resolvedEntitiesCount == referenceEntry.referencedEntities.size()) { Element element = create_arg->getAttr(referenceEntry.propertyName); resolveEntityReferences(element); create_arg->setAttr(referenceEntry.propertyName, element); resolvedAttributes.insert(referenceEntry.propertyName); } else { create_arg->removeAttr(referenceEntry.propertyName); } } //Remove those attributes that were resolved if (resolvedAttributes.size() == referenceMapEntryI->second.size()) { //All attributes were resolved, remove the entry completely. mEntitiesWithReferenceAttributes.erase(referenceMapEntryI); } else { //Only remove those entries that were destroyed. std::vector<ReferencedEntry> copy; for (auto& referenceEntry : referenceMapEntryI->second) { if (resolvedAttributes.find(referenceEntry.propertyName) == resolvedAttributes.end()) { copy.push_back(std::move(referenceEntry)); } } referenceMapEntryI->second = std::move(copy); } } Create create; create->setArgs1(create_arg); create->setFrom(mAvatarId); create->setSerialno(newSerialNumber()); mCreateEntityMapping.insert(std::make_pair(create->getSerialno(), obj->getId())); res.push_back(create); }
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; }
void test() { const double x1 = 3.5; const double y1 = -4.6; const double z1 = 2.0; const double x2 = 42.0; const double y2 = 7.0; std::vector<RootEntity> ent_vec(10); for(int i=0; i<10; i++) { DEBUG_PRINT(std::cout<<std::endl<<"round:"<<i<<std::endl); RootEntity human; //check for empty default: DEBUG_PRINT(std::cout<<"empty ok?"<<std::endl); Atlas::Message::ListType empty = human->getVelocityAsList(); if(i==0) check_float_list3(empty, 0.0, 0.0, 0.0); else check_float_list3(empty, 0.0, y2, 0.0); //check after setting it DEBUG_PRINT(std::cout<<"setting ok?"<<std::endl); Atlas::Message::ListType velocity; velocity.push_back(x1); velocity.push_back(y1); velocity.push_back(z1); check_float_list3(velocity, x1, y1, z1); human->setVelocityAsList(velocity); Atlas::Message::ListType foo = human->getVelocityAsList(); check_float_list3(foo, x1, y1, z1); DEBUG_PRINT(std::cout<<"changing it?"<<std::endl); std::vector<double> &foo2 = human->modifyVelocity(); *foo2.begin() = x2; check_float_list3(human->getVelocityAsList(), x2, y1, z1); DEBUG_PRINT(std::cout<<"check change result?"<<std::endl); foo = human->getVelocityAsList(); check_float_list3(foo, x2, y1, z1); DEBUG_PRINT(std::cout<<"std::vector of entities?"<<std::endl); const Atlas::Message::ListType &ent_velocity = ent_vec[i]->getVelocityAsList(); if(i==0) check_float_list3(ent_velocity, 0.0, 0.0, 0.0); else check_float_list3(ent_velocity, 0.0, y2, 0.0); DEBUG_PRINT(std::cout<<"base?"<<std::endl); RootEntity base_entity = Atlas::Objects::Entity::RootEntityData::allocator.getDefaultObjectInstance(); std::vector<double> &base = base_entity->modifyVelocity(); base[1] = y2; check_float_list3(base_entity->getVelocityAsList(), 0.0, y2, 0.0); RootOperation move_op; std::vector<Root> move_args(1); move_args[0] = human; move_op->setArgs(move_args); RootOperation sight_op; //sight_op->setFrom(humanent.asObjectPtr()); std::vector<Root> sight_args(1); sight_args[0] = move_op; sight_op->setArgs(sight_args); //test DEBUG_PRINT(std::cout<<"get move_op?"<<std::endl); const std::vector<Root>& test_args = sight_op->getArgs(); assert(test_args.size() == 1); RootOperation test_op = (RootOperation&)test_args[0]; DEBUG_PRINT(std::cout<<"get human_ent?"<<std::endl); const std::vector<Root>& test_args2 = test_op->getArgs(); assert(test_args2.size() == 1); RootEntity test_ent = (RootEntity&)test_args2[0]; Atlas::Message::ListType foo3 = test_ent->getVelocityAsList(); check_float_list3(foo3, x2, y1, z1); std::vector<double> coords(3, 0.0); human->setPos(coords); human->setVelocity(coords); human->modifyVelocity()[0] = 1.0; check_float_list3(human->getPosAsList(), 0.0, 0.0, 0.0); check_float_list3(human->getVelocityAsList(), 1.0, 0.0, 0.0); } }
void Juncture::addToEntity(const RootEntity & ent) const { ent->setObjtype("obj"); ent->setId(getId()); ent->setParents(std::list<std::string>(1,"juncture")); }
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 }
void AccountConnectionintegration::test_account_creation() { // Basic player account creation { ASSERT_NOT_NULL(m_connection); ASSERT_TRUE(m_connection->objects().empty()); Create op; Anonymous create_arg; create_arg->setParent("player"); create_arg->setAttr("username", "39d409ec"); create_arg->setAttr("password", "6a6e71bab281"); op->setArgs1(create_arg); ASSERT_TRUE(test_sent_ops.empty()); // Send the operation to create the account m_connection->externalOperation(op, *m_connection); // There should be a response op ASSERT_TRUE(!test_sent_ops.empty()); ASSERT_EQUAL(test_sent_ops.size(), 1u); // and the account creation should have created an object bound // to this connection. ASSERT_TRUE(!m_connection->objects().empty()); // Check the response is an info indicating successful account // creation. const Operation & reply = test_sent_ops.front(); ASSERT_EQUAL(reply->getClassNo(), Atlas::Objects::Operation::INFO_NO); // The Info response should have an argument describing the created // account const std::vector<Root> & reply_args = reply->getArgs(); ASSERT_TRUE(!reply_args.empty()); RootEntity account = smart_dynamic_cast<RootEntity>(reply_args.front()); ASSERT_TRUE(account.isValid()); // The account ID should be provided ASSERT_TRUE(!account->isDefaultId()); const std::string account_id = account->getId(); ASSERT_TRUE(!account_id.empty()); // Check the account has been registered in the server object Router * account_router_ptr = m_server->getObject(account_id); ASSERT_NOT_NULL(account_router_ptr); // Check the account has been logged into the lobby const auto & lobby_dict = m_server->m_lobby.getAccounts(); auto I = lobby_dict.find(account_id); ASSERT_TRUE(I != lobby_dict.end()); auto account_ptr = I->second; ASSERT_EQUAL(account_router_ptr, account_ptr); // Basic login as now been established by account creation // Set up some other account details create_arg->setAttr("username", "89cae312"); create_arg->setAttr("password", "d730b8bd2d6c"); // and try an additional account creation, which should fail. // Multiple logins are ok, but there is no reason to allow multiple // account creations. test_sent_ops.clear(); m_connection->externalOperation(op, *m_connection); ASSERT_TRUE(!test_sent_ops.empty()); ASSERT_EQUAL(test_sent_ops.size(), 1u); const Operation & error_reply = test_sent_ops.front(); ASSERT_EQUAL(error_reply->getClassNo(), Atlas::Objects::Operation::ERROR_NO); // TODO Character creation etc? // TODO Lobby interaction? // TODO Logout ? } }
void ServerRouting::addToEntity(const RootEntity & ent) const { ent->setObjtype("obj"); ent->setAttr("server", "cyphesis"); ent->setAttr("ruleset", m_svrRuleset); ent->setName(m_svrName); ent->setParent("server"); ent->setAttr("clients", m_numClients); ent->setAttr("uptime", m_world.upTime()); ent->setAttr("buildid", consts::buildId); ent->setAttr("version", std::string(consts::version)); if (restricted_flag) { ent->setAttr("restricted", "true"); } ent->setAttr("entities", (long)m_world.getEntities().size()); ent->setAttr("assets", Atlas::Message::ListType{"file://" + assets_directory}); // We could add all sorts of stats here, but I don't know exactly what yet. }
void AccountConnectionintegration::test_account_creation() { // Basic player account creation { ASSERT_NOT_NULL(m_connection); ASSERT_TRUE(m_connection->objects().empty()); Create op; Anonymous create_arg; create_arg->setParents(std::list<std::string>(1, "player")); create_arg->setAttr("username", "39d409ec"); create_arg->setAttr("password", "6a6e71bab281"); op->setArgs1(create_arg); ASSERT_TRUE(test_sent_ops.empty()); // Send the operation to create the account m_connection->externalOperation(op, *m_connection); // There should be a response op ASSERT_TRUE(!test_sent_ops.empty()); ASSERT_EQUAL(test_sent_ops.size(), 1u); // and the account creation should have created an object bound // to this connection. ASSERT_TRUE(!m_connection->objects().empty()); // Check the response is an info indicating successful account // creation. const Operation & reply = test_sent_ops.front(); ASSERT_EQUAL(reply->getClassNo(), Atlas::Objects::Operation::INFO_NO); // The Info response should have an argument describing the created // account const std::vector<Root> & reply_args = reply->getArgs(); ASSERT_TRUE(!reply_args.empty()); RootEntity account = smart_dynamic_cast<RootEntity>(reply_args.front()); ASSERT_TRUE(account.isValid()); // The account ID should be provided ASSERT_TRUE(!account->isDefaultId()); const std::string account_id = account->getId(); ASSERT_TRUE(!account_id.empty()); // Check the account has been registered in the server object Router * account_router_ptr = m_server->getObject(account_id); ASSERT_NOT_NULL(account_router_ptr); // Check the account has been logged into the lobby const AccountDict & lobby_dict = m_server->m_lobby.getAccounts(); AccountDict::const_iterator I = lobby_dict.find(account_id); ASSERT_TRUE(I != lobby_dict.end()); Account * account_ptr = I->second; ASSERT_EQUAL(account_router_ptr, account_ptr); // Basic login as now been established by account creation // Set up some other account details create_arg->setAttr("username", "89cae312"); create_arg->setAttr("password", "d730b8bd2d6c"); // and try an additional account creation, which should fail. // Multiple logins are ok, but there is no reason to allow multiple // account creations. test_sent_ops.clear(); m_connection->externalOperation(op, *m_connection); ASSERT_TRUE(!test_sent_ops.empty()); ASSERT_EQUAL(test_sent_ops.size(), 1u); const Operation & error_reply = test_sent_ops.front(); ASSERT_EQUAL(error_reply->getClassNo(), Atlas::Objects::Operation::ERROR_NO); Player::playableTypes.insert(test_valid_character_type); Anonymous character_arg; character_arg->setParents(std::list<std::string>(1, test_valid_character_type)); character_arg->setName("938862f2-4db2-4e8e-b944-7b0935e569db"); Create character_op; character_op->setArgs1(character_arg); character_op->setFrom(account_id); test_sent_ops.clear(); m_connection->externalOperation(character_op, *m_connection); // FIXME the above went through Account::externalOperation, so there // is no reply in res. The reply has gone directly to the Link::send // method. Add a way of checking, once there are better stubs. ASSERT_TRUE(!test_sent_ops.empty()); ASSERT_EQUAL(test_sent_ops.size(), 2u); const Operation & create_reply = test_sent_ops.front(); ASSERT_EQUAL(create_reply->getClassNo(), Atlas::Objects::Operation::INFO_NO); // TODO Character creation etc? // TODO Lobby interaction? // TODO Logout ? } }
void testXML() { RootEntity human; human->setId("foo"); Move move_op; move_op->setFrom(std::string("bar")); std::vector<Root> move_args(1); move_args[0] = human; move_op->setArgs(move_args); Atlas::Message::ListType velocity; velocity.push_back(2.0); velocity.push_back(1.0); velocity.push_back(0.0); human->setVelocityAsList(velocity); // typedef BaseObjectData *(*alloc_func)(); // alloc_func alloc_entity = &Entity::RootEntityDataInstance::alloc; // BaseObjectData *bod = alloc_entity(); //Root human2(bod); Root human2 = Atlas::Objects::factory<Atlas::Objects::Entity::RootEntityData>("root_enitty", Atlas::Objects::Entity::RootEntity()->getClassNo()); std::cout<<"human.id="<<human->getId()<<std::endl; std::cout<<"human2.id="<<human2->getId()<<std::endl; #if 0 typedef std::list<Atlas::Factory<Atlas::Codec >*> FactoryCodecs; FactoryCodecs *myCodecs = &Factory<Codec >::factories(); FactoryCodecs::iterator i; std::cout<<"myCodecs: "<<myCodecs->size(); for (i = myCodecs->begin(); i != myCodecs->end(); ++i) std::cout<<":"<<(*i)->getName(); std::cout<<std::endl; #endif //DebugBridge bridge; TestDecoder bridge; #if USE_FILE fstream stream; std::string atlas_xml_path; char * srcdir_env = getenv("srcdir"); if (srcdir_env != 0) { atlas_xml_path = srcdir_env; atlas_xml_path += "/"; } atlas_xml_path += "../../protocol/spec/atlas.xml"; stream.open(atlas_xml_path, std::ios::in); assert(!!stream); #else std::stringstream stream; #endif // typedef std::list<Atlas::Factory<Atlas::Codec >*> FactoryCodecs; // FactoryCodecs *myCodecs = &Factory<Codec >::factories(); // FactoryCodecs::iterator codec_i; // Atlas::Codec *codec = NULL; // for(codec_i = myCodecs->begin(); codec_i != myCodecs->end(); ++codec_i) // { // std::cout<<(*codec_i)->getName()<<std::endl; // if ((*codec_i)->getName() == "XML") { // codec = (*codec_i)->New(Codec::Parameters(stream, &bridge)); // } // } // assert(codec); Account account; Login l; account->setAttr("id", std::string("al")); account->setAttr("password", std::string("ping")); //list<Message::Object> args(1,account->asObject()); //l->setArgsAsList(args); std::vector<Root> args(1); args[0] = account; l->setArgs(args); //coder->streamObjectsMessage((Root&)l); //<map><list name="args"><map><std::string name="id">al</strin //g></map></list><list name="parents"><std::string>root</std::string></list><std::string name="ob //jtype">op_definition</std::string></map> Atlas::Codec *codec; #if USE_XML codec = new Atlas::Codecs::XML((std::iostream&)stream, bridge); #else codec = new Atlas::Codecs::Packed(stream, bridge); #endif assert(codec); #if USE_FILE while(stream) { codec->poll(); //std::cout<<"--------"<<std::endl; } #else codec->streamBegin(); Atlas::Objects::ObjectsEncoder eno(*codec); // eno.streamObjectsMessage(move_op); eno.streamObjectsMessage(l); Anonymous e; eno.streamObjectsMessage(e); e->setId("foo"); eno.streamObjectsMessage(e); // Atlas::Message::Encoder en(codec); // en.streamObjectsMessage(human->asObject()); codec->streamEnd(); std::cout<<std::endl<<stream.str()<<std::endl; //[$from=bar(args=[$id=foo])][$id=foo] //<atlas><map><std::string name="from">bar</std::string><list name="args"><map><std::string name="id">foo</std::string></map></list></map><map><std::string name="id">foo</std::string></map></atlas> #endif delete codec; }