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()); }
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 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); }
void World::RelayOperation(const Operation & op, OpVector & res) { //A Relay operation with refno sent to ourselves signals that we should prune //our registered relays in m_relays. This is a feature to allow for a timeout; if //no Relay has been received from the destination Entity after a certain period //we'll shut down the relay link. if (op->getTo() == getId() && op->getFrom() == getId() && !op->isDefaultRefno()) { auto I = m_relays.find(op->getRefno()); if (I != m_relays.end()) { //Send an empty operation to signal that the relay has expired. I->second.callback(Operation(), I->second.entityId); m_relays.erase(I); } } else { if (op->getArgs().empty()) { log(ERROR, "World::RelayOperation no args."); return; } Operation relayedOp = Atlas::Objects::smart_dynamic_cast<Operation>( op->getArgs().front()); if (!relayedOp.isValid()) { log(ERROR, "World::RelayOperation first arg is not an operation."); return; } //If a relay op has a refno, it's a response to a Relay op previously sent out to another //entity, and we should signal that we have an incoming relayed op. if (!op->isDefaultRefno()) { //Note that the relayed op should be considered untrusted in this case, as it has originated //from a random entity or its mind. auto I = m_relays.find(op->getRefno()); if (I == m_relays.end()) { log(WARNING, "World::RelayOperation could not find registrered Relay with refno."); return; } //Make sure that this op really comes from the entity the original Relay op was sent to. if (op->getFrom() != I->second.entityId) { log(WARNING, "World::RelayOperation got relay op with mismatching 'from'."); return; } //Get the relayed operation and call the callback. I->second.callback(relayedOp, I->second.entityId); m_relays.erase(I); } else { //Send it on to the basic Entity relay mechanism Entity::RelayOperation(op, res); } } }
void ConnectionCharacterintegration::test_external_op() { // Dispatching a Talk external op from the character should result in // it being passed on to the world. m_character->linkExternal(m_connection); Atlas::Objects::Operation::Talk op; op->setFrom(m_character->getId()); m_connection->externalOperation(op, *m_connection); // BaseWorld::message should have been called from Enitty::sendWorld // with the Talk operation, modified to have TO set to the character. 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(), m_character->getId()); ASSERT_NOT_NULL(m_BaseWorld_message_called_from); ASSERT_EQUAL(m_BaseWorld_message_called_from, m_character); }
void TrustedConnectionCreatorintegration::test_external_op_override() { // Dispatching a Talk external op from the creator should result in // it being passed on to the world, exactly as if this was a Character // except that we assume that Creator was set up linked. m_creator->m_externalMind = new ExternalMind(*m_creator); m_creator->m_externalMind->linkUp(m_connection); Atlas::Objects::Operation::Talk op; op->setFrom(m_creator->getId()); op->setTo(m_creator->getId()); m_connection->externalOperation(op, *m_connection); // The operation should have been passed to Entity::callOperation for // dispatch, completely unfiltered. ASSERT_TRUE(m_Entity_callOperation_called.isValid()); ASSERT_EQUAL(m_Entity_callOperation_called->getClassNo(), Atlas::Objects::Operation::TALK_NO); ASSERT_TRUE(!m_Entity_callOperation_called->isDefaultTo()); ASSERT_EQUAL(m_Entity_callOperation_called->getTo(), m_creator->getId()); }
void TrustedConnectionCreatorintegration::test_external_op() { // Dispatching a Talk external op from the creator should result in // it being passed on to the world, exactly as if this was a Character // except that we assume that Creator was set up linked. m_creator->m_externalMind = new ExternalMind(*m_creator); m_creator->m_externalMind->linkUp(m_connection); Atlas::Objects::Operation::Talk op; op->setFrom(m_creator->getId()); m_connection->externalOperation(op, *m_connection); // BaseWorld::message should have been called from Enitty::sendWorld // with the Talk operation, modified to have TO set to the character. 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(), m_creator->getId()); ASSERT_NOT_NULL(m_BaseWorld_message_called_from); ASSERT_EQUAL(m_BaseWorld_message_called_from, m_creator); }
void Interactive::soundArrived(const Operation & op) { if (m_accountId.empty()) { return; } if (m_accountId != op->getTo()) { // This is an IG op we are monitoring return; } reply_flag = true; if (op->getArgs().empty()) { std::cout << "Sound op has no args" << std::endl << std::flush; return; } Operation sub_op = smart_dynamic_cast<Operation>(op->getArgs().front()); if (!sub_op.isValid()) { return; } if (sub_op->isDefaultFrom()) { std::cout << "Sound arg has no from" << std::endl << std::flush; return; } const std::string & from = sub_op->getFrom(); if (sub_op->getArgs().empty()) { std::cout << "Sound arg has no args" << std::endl << std::flush; return; } const Root & arg = sub_op->getArgs().front(); Element say; if (arg->copyAttr("say", say) != 0 || !say.isString()) { std::cout << "Sound arg arg has no say" << std::endl << std::flush; return; } std::cout << "[" << from << "] " << say.String() << std::endl << std::flush; }
void OperationMonitor::operation(const Operation & op, OpVector &) { ++op_count; std::cout << op->getParents().front() << "(from=\"" << op->getFrom() << "\",to=\"" << op->getTo() << "\")" << std::endl << std::flush; }