void CharacterCreationTracker::handleDatabaseCreateCharacterSuccess(StationId account, const Unicode::String &characterName, const NetworkId &characterObjectId, int templateId, bool jedi)
{
	// - Check we are at the right stage
	LOG("TraceCharacterCreation", ("%d DatabaseCreateCharacterSuccess(%s)", account, characterObjectId.getValueString().c_str()));
	CreationsType::iterator creationRecord=m_creations.find(account);
	if (creationRecord==m_creations.end() || creationRecord->second->m_stage != CreationRecord::S_sentToGameServer)
	{
		LOG("TraceCharacterCreation", ("%d DatabaseCreateCharacterSuccess was unexpected - exiting", account));
		DEBUG_WARNING(true,("Programmer bug:  got GameCreateCharacter message for accout %d, which we weren't expecting.\n",account));
		return;
	}

	// - Tell the login server to add the character
	LoginCreateCharacterMessage *msg = new LoginCreateCharacterMessage(account,characterName,characterObjectId,templateId,jedi);
	creationRecord->second->m_loginCreationRequest = msg;
	creationRecord->second->m_characterId = characterObjectId;
	uint32 loginServerId = CentralServer::getInstance().sendToArbitraryLoginServer(*msg, false);
	if (loginServerId != 0)
	{
		creationRecord->second->m_loginServerId = loginServerId;
		creationRecord->second->m_stage = CreationRecord::S_sentToLoginServer;
		LOG("TraceCharacterCreation", ("%d sending LoginCreateCharacterMessage", account));
	}
	else
	{
		creationRecord->second->m_loginServerId = 0;
		creationRecord->second->m_stage = CreationRecord::S_queuedForLoginServer;
		LOG("TraceCharacterCreation", ("%d waiting for login server", account));
	}
}
CellPermissions::PermissionObject::PermissionObject( const std::string& name ) :
	m_originalPermissionFormat( PF_UNKNOWN_STRING ),
	m_permissionString( Unicode::getTrim(name) )
{
	// See if we have a guild name
	if (_strnicmp( name.c_str(), "Guild:", 6 ) == 0 )
	{
		// Try to convert the name to a guild ID
		int guildId = GuildInterface::findGuild( Unicode::getTrim((name).substr(6)) );
		if ( guildId != 0 )
		{
			// Convert the guild ID to a string
			char buffer[32];
			sprintf( buffer, "%d", guildId );

			m_originalPermissionFormat = PF_GUILD_NAME;
			m_permissionString         = buffer;
		}
		else
		{
			// We will leave the format as "unknown" and keep the raw string
		}
	}
	else
	{
		// The name string might be an actual name or a network ID...

		// See if there are any characters in the string
		std::string::size_type idx = name.find_first_not_of( "1234567890" );
		if ( idx == std::string::npos )
		{
			// Everything in the string is a number
			m_originalPermissionFormat = PF_NUMERIC_VALUE;
			m_permissionString         = name;
		}
		else
		{
			// Try to convert the name to a network ID
			const NetworkId playerNetworkId = NameManager::getInstance().getPlayerId( NameManager::normalizeName( name ) );
			if ( playerNetworkId != NetworkId::cms_invalid )
			{
				// We found the network ID for the player
				m_originalPermissionFormat = PF_CHARACTER_NAME;
				m_permissionString         = playerNetworkId.getValueString();
			}
			else
			{
				// We will leave the format as "unknown" and keep the raw string
			}
		}
	}
}
void PlanetProxyObject::addContainedObject(const NetworkId &theObject)
{
	if (!m_contents)
	{
		m_contents = new std::vector<NetworkId>;
	}
	for (std::vector<NetworkId>::const_iterator i=m_contents->begin(); i!=m_contents->end(); ++i)
	{
		if (*i==theObject)
			WARNING(true,("Object %s was placed in container %s twice.", theObject.getValueString().c_str(), m_objectId.getValueString().c_str()));
	}
	m_contents->push_back(theObject);
}
	void logBaselines(NetworkId const &senderId, char const *messageType, std::vector<NetworkId> const & clients)
	{
		if (!ConfigServerGame::getLogBaselines())
			return;

		for (std::vector<NetworkId>::const_iterator i = clients.begin(); i != clients.end(); ++i)
		{
			DEBUG_REPORT_LOG(true, ("Baselines: %s for object %s to client %s\n", messageType, senderId.getValueString().c_str(), (*i).getValueString().c_str()));
			LOG(
				"Baselines",
				(
					"%s for object %s to client %s",
					messageType,
					senderId.getValueString().c_str(),
					(*i).getValueString().c_str()));
		}
	}
void MarketAuctionsBufferUpdate::addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRowUpdate *row)
{
	DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Adding row to Index. ItemId : %s.\n", itemId.getValueString().c_str()));
	m_rows[itemId]=row;
}
Exemple #6
0
//-----------------------------------------------------------------------------
void ChatLogManager::getReportHeader(Unicode::String & header, std::string const &reportingPlayer, NetworkId const &reportingPlayerNetworkId, std::string const &reportingPlayerStationName, uint32 reportingPlayerStationId, std::string const &harassingPlayer, NetworkId const &harassingPlayerNetworkId, std::string const &harassingPlayerStationName, uint32 harassingPlayerStationId)
{
    header.clear();
    header.append(Unicode::narrowToWide("\n\n//--------------------------------------------------------\n"));

    FormattedString<512> fs;

    // Reporting

    header.append(Unicode::narrowToWide(fs.sprintf("Reporting: %s (%s)", reportingPlayer.c_str(), reportingPlayerNetworkId.getValueString().c_str())));

    if (!reportingPlayerStationName.empty() || (reportingPlayerStationId > 0))
    {
        header.append(Unicode::narrowToWide(" Station ID:"));
        if (!reportingPlayerStationName.empty())
            header.append(Unicode::narrowToWide(fs.sprintf(" %s", reportingPlayerStationName.c_str())));
        if (reportingPlayerStationId > 0)
            header.append(Unicode::narrowToWide(fs.sprintf(" (%lu)", reportingPlayerStationId)));
    }

    header.append(Unicode::narrowToWide("\n"));

    // Harassing

    header.append(Unicode::narrowToWide(fs.sprintf("Harassing: %s (%s)", harassingPlayer.c_str(), harassingPlayerNetworkId.getValueString().c_str())));

    if (!harassingPlayerStationName.empty() || (harassingPlayerStationId > 0))
    {
        header.append(Unicode::narrowToWide(" Station ID:"));
        if (!harassingPlayerStationName.empty())
            header.append(Unicode::narrowToWide(fs.sprintf(" %s", harassingPlayerStationName.c_str())));
        if (harassingPlayerStationId > 0)
            header.append(Unicode::narrowToWide(fs.sprintf(" (%lu)", harassingPlayerStationId)));
    }

    header.append(Unicode::narrowToWide("\n"));

    // Creation time

    header.append(Unicode::narrowToWide(fs.sprintf("Log Creation Time: %s\n", getTimeString(Os::getRealSystemTime()).c_str())));

    // Time length

    header.append(Unicode::narrowToWide(fs.sprintf("Log Time Length: %d minutes\n", ConfigServerUtility::getChatLogMinutes())));
}
/**
 * Update an object with new data sent from a game server.
 * Checks to see what changed, then takes appropriate actions.
 */
void PlanetProxyObject::update(int x, int y, int z, NetworkId containedBy, uint32 authoritativeServer, int interestRadius, int objectTypeTag, int const level, bool const hibernating, uint32 const templateCrc, int const aiActivity, int const creationType)
{
	WARNING_DEBUG_FATAL(m_objectId==NetworkId::cms_invalid,("Object ID was 0."));
	bool watcherUpdateNeeded = false;

	m_level = level;
	m_hibernating = hibernating;
	m_templateCrc = templateCrc;
	m_aiActivity = aiActivity;
	m_creationType = creationType;

	if ((m_authoritativeServer != 0 ) && (authoritativeServer != m_authoritativeServer) && (containedBy == NetworkId::cms_invalid))
	{
		static unsigned long authTransferSanityCheckTimeMs = ConfigPlanetServer::getAuthTransferSanityCheckTimeMs();
		if (Clock::timeMs()-m_authTransferTimeMs > authTransferSanityCheckTimeMs)
		{
			WARNING(true, ("Resending auth transfer for %s to %lu due to receiving a stale position update.", m_objectId.getValueString().c_str(), authoritativeServer));
			sendAuthorityChange(authoritativeServer, m_authoritativeServer, false);
			return;
		}
		if (ConfigPlanetServer::getLogObjectLoading())
			LOG("ObjectLoading",("Ignoring update for %s from %lu because server was not authoritative.",m_objectId.getValueString().c_str(),authoritativeServer));
		return;
	}
	
	if (interestRadius>ConfigPlanetServer::getMaxInterestRadius())
		interestRadius = ConfigPlanetServer::getMaxInterestRadius();
	
	if (interestRadius>0 && PlanetServer::getInstance().isInTutorialMode())
		interestRadius = 1;

	if (containedBy!=NetworkId::cms_invalid)
	{
		// get coordinates from container
		PlanetProxyObject *container = Scene::getInstance().findObjectByID(containedBy);
		if (container)
		{
			x=container->getX();
			y=container->getY();
			z=container->getZ();
		}
		else
		{
			LOG("PlanetUpdate",("Game server said object %s was contained by object %s, but we could not find the container.",m_objectId.getValueString().c_str(),containedBy.getValueString().c_str()));
			containedBy = NetworkId::cms_invalid; // so that we'll try again when the object moves again, in case we just got objects out-of-order from the game server
		}
	}
	
	std::vector<uint32> oldProxyList;

	Node *newNode=Scene::getInstance().findNodeByPosition(x,z);
	NOT_NULL(newNode);
	if (newNode!=m_quadtreeNode || m_interestRadius != interestRadius || m_authoritativeServer != authoritativeServer || m_containedBy != containedBy)
	{
		watcherUpdateNeeded = true;

		// For debugging, update the contents of the containers
		if (ConfigPlanetServer::getEnableContentsChecking() && (m_containedBy!=containedBy))
			updateContentsTracking(containedBy);
		
		bool const firstUpdate = (m_quadtreeNode == NULL);

		if (m_quadtreeNode!=NULL) // if this is the first update for this object, m_quadtreeNode will be NULL because it hasn't been placed anywhere yet
		{
			removeServerStatistics();

			// remember old list of proxies
			getServers(oldProxyList);
			
			// remove from the old location
			m_quadtreeNode->removeObject(this);

			if (ConfigPlanetServer::getLogObjectLoading())
				LOG("ObjectLoading", ("unsubscribing nodes for object id=[%s]", m_objectId.getValueString().c_str()));
			unsubscribeSurroundingNodes(false);
		}
		
		// update data
		m_quadtreeNode=newNode;
		m_x=x;
		m_y=y;
		m_z=z;
		m_interestRadius=interestRadius;
		m_objectTypeTag = objectTypeTag;
		m_authoritativeServer=authoritativeServer;
		m_containedBy=containedBy;

		// make sure the destination is loaded
		if (!newNode->isLoaded())
		{
			if (ConfigPlanetServer::getLogObjectLoading())
				LOG("ObjectLoading",("Loading node %s because object %s entered it.",newNode->getDebugNodeString().c_str(), m_objectId.getValueString().c_str()));
			newNode->load();
		}
			
		// check if we're on the right server
		if (!isAuthorityOk())
		{
			uint32 preferredServer = m_quadtreeNode->getPreferredServer();
			if (m_containedBy==NetworkId::cms_invalid)
			{
				if (ConfigPlanetServer::getLogObjectLoading())
					LOG("ObjectLoading",("Changing authority for object %s from %lu to %lu because node %s is authoritative on that server.",
										 m_objectId.getValueString().c_str(),m_authoritativeServer,preferredServer,m_quadtreeNode->getDebugNodeString().c_str()));
				changeAuthority(preferredServer, false, false); // changes m_authoritativeServer and sends message

				// we received the object for the first time, and we had to
				// transfer the object's authority, so we need to make sure
				// to unload the object on the current authoritative server,
				// if necessary
				if (firstUpdate)
					oldProxyList.push_back(authoritativeServer);
			}
			else
			{
				WARNING(true,("Programmer bug:  Object %s is in container %s, which is node %s.  The object should be authoritative on server %i but it is authoritative on server %i.",
							  m_objectId.getValueString().c_str(),m_containedBy.getValueString().c_str(),m_quadtreeNode->getDebugNodeString().c_str(), m_authoritativeServer, preferredServer));
			}
		}

		// place in the new location
		newNode->addObject(this);

		if (interestRadius > 0)
		{
			if (ConfigPlanetServer::getLogObjectLoading())
				LOG("ObjectLoading", ("subscribing nodes for object id=[%s]", m_objectId.getValueString().c_str()));
			subscribeSurroundingNodes();		
		}
		
		// check against new interested servers, and send proxy/unproxy as needed
		if (m_containedBy==NetworkId::cms_invalid) // we don't manage proxies for containers
		{
			std::vector<uint32> newProxyList;
			getServers(newProxyList);
			changeProxies(oldProxyList,newProxyList);
		}
		
		addServerStatistics();
	}  
	else
	{
		if (m_interestRadius > 0 || (abs(m_x - x) > 25) || (abs(m_z - z) > 25))
			watcherUpdateNeeded = true;
	}
		
	if (PlanetServer::getInstance().isWatcherPresent() && watcherUpdateNeeded)
	{
		m_x=x;
		m_y=y;
		m_z=z;
		m_objectTypeTag = objectTypeTag;

		outputStatusToAll(false);
	}
}
/**
 * Helper function to update the contents tracking lists, in order to
 * debug various authority problems
 */
void PlanetProxyObject::updateContentsTracking(const NetworkId &newContainedBy)
{
	if (m_containedBy!=NetworkId::cms_invalid)
	{
		PlanetProxyObject *container = Scene::getInstance().findObjectByID(m_containedBy);
		if (container)
			container->removeContainedObject(m_objectId);
		else
			WARNING(true,("Removing object %s from container %s, but the container could not be found.",m_objectId.getValueString().c_str(), m_containedBy.getValueString().c_str()));
	}

	if (newContainedBy!=NetworkId::cms_invalid)
	{
		PlanetProxyObject *container = Scene::getInstance().findObjectByID(newContainedBy);
		if (container)
			container->addContainedObject(m_objectId);
		else
			WARNING(true,("Adding object %s to container %s, but the container could not be found.",m_objectId.getValueString().c_str(), newContainedBy.getValueString().c_str()));
	}
}
void CreatureObjectBuffer::setAttribute(const NetworkId &objectId, Attributes::Enumerator type, Attributes::Value value)
{
	DBSchema::CreatureObjectBufferRow *row=dynamic_cast<DBSchema::CreatureObjectBufferRow*>(findRowByIndex(objectId));
	if (row==0)
	{
		row=addEmptyRow(objectId);
	}
	
	switch (type)
	{
		case 0:
			row->attribute_0=value;
			break;
		case 1:
			row->attribute_1=value;
			break;
		case 2:
			row->attribute_2=value;
			break;
		case 3:
			row->attribute_3=value;
			break;
		case 4:
			row->attribute_4=value;
			break;
		case 5:
			row->attribute_5=value;
			break;
		case 6:
			row->attribute_6=value;
			break;
		case 7:
			row->attribute_7=value;
			break;
		case 8:
			row->attribute_8=value;
			break;
		case 9:
			row->attribute_9=value;
			break;
		case 10:
			row->attribute_10=value;
			break;
		case 11:
			row->attribute_11=value;
			break;
		case 12:
			row->attribute_12=value;
			break;
		case 13:
			row->attribute_13=value;
			break;
		case 14:
			row->attribute_14=value;
			break;
		case 15:
			row->attribute_15=value;
			break;
		case 16:
			row->attribute_16=value;
			break;
		case 17:
			row->attribute_17=value;
			break;
		case 18:
			row->attribute_18=value;
			break;
		case 19:
			row->attribute_19=value;
			break;
		case 20:
			row->attribute_20=value;
			break;
		case 21:
			row->attribute_21=value;
			break;
		case 22:
			row->attribute_22=value;
			break;
		case 23:
			row->attribute_23=value;
			break;
		case 24:
			row->attribute_24=value;
			break;
		case 25:
			row->attribute_25=value;
			break;
		case 26:
			row->attribute_26=value;
			break;
		
		default:
			WARNING_STRICT_FATAL(true,("Programmer bug:  setAttribute(%s, %i, %i):  %i is not a valid attribute identifier",objectId.getValueString().c_str(), type, value, type));
	}
}
void SwgSnapshot::encodeAttributes(const NetworkId &objectId, Archive::ByteStream &data, int offset) const
{
	std::vector<Attributes::Value> values;
	m_creatureObjectBuffer.getAttributesForObject(objectId, values, offset, Attributes::NumberOfAttributes);
	
	Archive::put(data, Attributes::NumberOfAttributes);
	Archive::put(data, static_cast<size_t>(0)); // baselineCommandCount
	if (values.size() < static_cast<size_t>(Attributes::NumberOfAttributes))
	{
		DEBUG_REPORT_LOG(true,("Object %s did not have valid attribute data in the database.  Missing attributes will be set to 100.\n",objectId.getValueString().c_str()));
		values.resize(Attributes::NumberOfAttributes, 100);
	}
	for (int i=0; i<Attributes::NumberOfAttributes; ++i)
	{
		Archive::put(data,values[i]);
	}
}
void SwgSnapshot::encodeSingleWaypoint(const NetworkId &objectId, Archive::ByteStream &data) const
{
	typedef std::vector<PersistableWaypoint> ValuesType;
	ValuesType values;
	m_waypointBuffer.getWaypointsForObject(objectId, values);

	DEBUG_FATAL(values.size()!=1,("Object %s should have exactly 1 waypoint, but it has %i",objectId.getValueString().c_str(),values.size()));
	
	ValuesType::const_iterator i=values.begin();
	if (i!=values.end())
		Archive::put(data,*i);
	else
		Archive::put(data,PersistableWaypoint());
}
// ----------------------------------------------------------------------
void SpaceAttackSquad::onAddUnit(NetworkId const & unit)
{
	AiShipController * const aiShipController = AiShipController::getAiShipController(unit);
	
	if (aiShipController != NULL)
	{
		aiShipController->setAttackSquad(this);
	}
	else
	{
#ifdef _DEBUG
		FormattedString<1024> fs;
		char const * const text = fs.sprintf("SpaceAttackSquad::onAddUnit() id(%d) ERROR: Trying to add a unit(%s) that can't resolve to an AiShipController.", getId(), unit.getValueString().c_str());
		DEBUG_WARNING(true, (text));
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", (text));
#endif // _DEBUG
	}

	calculateAttackRanges();
}
// ----------------------------------------------------------------------
void SpaceAttackSquad::addDamageTaken(NetworkId const & attackingUnit, float const damage) const
{
	LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("SpaceAttackSquad::addDamageTaken() squadId(%d) attackingUnit(%s) damage(%.f)", getId(), attackingUnit.getValueString().c_str(), damage));

	UnitMap const & unitMap = getUnitMap();
	UnitMap::const_iterator iterUnitMap = unitMap.begin();

	for (; iterUnitMap != unitMap.end(); ++iterUnitMap)
	{
		NetworkId const & unit = iterUnitMap->first;
		bool const notifySquad = false;
		bool const checkPlayerAttacker = true;

		IGNORE_RETURN(AiShipControllerInterface::addDamageTaken(unit, attackingUnit, damage, notifySquad, checkPlayerAttacker));
	}
}
// ----------------------------------------------------------------------
void SpaceAttackSquad::onSetUnitFormationPosition_l(NetworkId const & unit, Vector const & position_l)
{
	AiShipController * const aiShipController = AiShipController::getAiShipController(unit);

	if (aiShipController != NULL)
	{
		aiShipController->setAttackFormationPosition_l(position_l);
	}
	else
	{
#ifdef _DEBUG
		FormattedString<1024> fs;
		char const * const text = fs.sprintf("SpaceAttackSquad::onSetUnitFormationPosition_l() ERROR: Unable to resolve AiShipController for unit(%s)", unit.getValueString().c_str());
		DEBUG_WARNING(true, (text));
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", (text));
#endif // _DEBUG
	}
}
void MessageToQueue::sendRecurringMessageToJava(const NetworkId &objectId, const std::string &method, const stdvector<int8>::fwd &packedData, int delay)
{
	WARNING_DEBUG_FATAL(delay < 0, ("Sent messageTo with negative delay.  Target %s, method %s, delay %f",objectId.getValueString().c_str(), method.c_str(), delay));
	if (delay < 0)
		delay = 0;

	MessageToPayload messageData(objectId, ObjectIdManager::getNewObjectId(), method, packedData, ServerClock::getInstance().getGameTimeSeconds() + static_cast<unsigned long>(delay), false, MessageToPayload::DT_java, NetworkId::cms_invalid, ms_nullString, delay);
	internalSendMessageTo(messageData);
}
/**
 * Send a message from an object to another, to be handled by a Java
 * script.
 */
void MessageToQueue::sendMessageToJava (const NetworkId &objectId, const std::string &method, const std::vector<int8> &packedData, int delay, bool guaranteed, NetworkId const & undeliveredCallbackObject, std::string const & undeliveredCallbackMethod)
{
	WARNING_DEBUG_FATAL(delay < 0, ("Sent messageTo with negative delay.  Target %s, method %s, delay %f",objectId.getValueString().c_str(), method.c_str(), delay));
	if (delay < 0)
		delay = 0;

	MessageToPayload messageData(objectId, ObjectIdManager::getNewObjectId(), method, packedData, ServerClock::getInstance().getGameTimeSeconds() + static_cast<unsigned long>(delay), guaranteed, MessageToPayload::DT_java, undeliveredCallbackObject, undeliveredCallbackMethod, 0);
	internalSendMessageTo(messageData);
}
void CommoditiesSnapshot::newObject(NetworkId const & objectId, int templateId, Tag typeId)
{
	WARNING(true,("Attempt to create object %s.  It has unknown type %i.",objectId.getValueString().c_str(),typeId));
}
void PositionUpdateTracker::sendPositionUpdate(ServerObject &obj)
{
	if (!s_installed)
		return;

	std::map<ServerObject *, ServerObject **>::iterator i = s_positionUpdateCallbackMap.find(&obj);
	if (i != s_positionUpdateCallbackMap.end())
	{
		*((*i).second) = 0;
		s_positionUpdateCallbackMap.erase(i);
	}

	if (!shouldSendPositionUpdate(obj))
		return;

	if (ConfigServerGame::getLogPositionUpdates())
	{
		LOG("PositionUpdate", ("Sending position update for %s", obj.getNetworkId().getValueString().c_str()));
	}

	NetworkId const loadWithId = ContainerInterface::getLoadWithContainerId(obj);

	//-- Determine Object container's network id and Object's arrangement as far as the Database is concerned.
	NetworkId containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(obj)->getContainedByNetworkId();
	int objectArrangementForDatabase = ContainerInterface::getSlottedContainmentProperty(obj)->getCurrentArrangement();
	Transform transformForDatabase(obj.getTransform_o2p());
	Transform worldspaceTransformForDatabase(obj.getTransform_o2w());

	// if it's a player inside a container, the world space coordinate
	// that should be saved is the world space coordinate of the topmost
	// container; this way, player logging out of a house will get
	// loaded back into the same game server as the house, thus maximizing
	// that chance that the player will loaded back into the house
	if (obj.isPlayerControlled() && obj.asCreatureObject())
	{
		Object const *containerObj = ContainerInterface::getTopmostContainer(obj);
		if (containerObj && (containerObj != &obj))
		{
			worldspaceTransformForDatabase = containerObj->getTransform_o2w();
		}
	}

	// Ships should be persisted in their ship control device if they have one
	ShipObject const * const ship = obj.asShipObject();
	if (ship)
	{
		ServerObject const * const shipControlDevice = ship->getControlDevice();
		if (shipControlDevice)
		{
			containerNetworkIdForDatabase = shipControlDevice->getNetworkId();
			objectArrangementForDatabase = -1;
			transformForDatabase.resetRotateTranslate_l2p();
		}
	}
	else
	{
		ShipObject const * const containingShip = ShipObject::getContainingShipObject(&obj);

		if (obj.isPlayerControlled())
		{
			if (containingShip)
			{
				// Player controlled objects in ships persist at the location of the ship.
				// Note: we need a more general solution if we decide to allow ships in interiors of ships.
				containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(*containingShip)->getContainedByNetworkId();
				objectArrangementForDatabase = -1;
				transformForDatabase = containingShip->getTransform_o2p();
			}
			else
			{
				ServerObject const * const container = safe_cast<ServerObject const *>(ContainerInterface::getContainedByObject(obj));
				CreatureObject const * const creatureContainer = (container ? container->asCreatureObject() : NULL);
				if (creatureContainer && creatureContainer->isMountable())
				{
					// Riders of mounts persist at the location of the mount
					containerNetworkIdForDatabase = ContainerInterface::getContainedByProperty(*creatureContainer)->getContainedByNetworkId();
					objectArrangementForDatabase = -1;
					transformForDatabase = creatureContainer->getTransform_o2p();
				}
			}
		}
	}

	// Make sure we aren't about to try to save an invalid containment/load_with state
	if (containerNetworkIdForDatabase == NetworkId::cms_invalid && loadWithId != obj.getNetworkId())
	{
		WARNING_DEBUG_FATAL(true, ("Tried to send a position update to the db for object %s with load_with=%s but contained_by=0!", obj.getNetworkId().getValueString().c_str(), loadWithId.getValueString().c_str()));
		obj.unload();
		return;
	}

	// Make sure we aren't about to try to save a persisted non-player in a space scene away from the origin
	FATAL(ServerWorld::isSpaceScene() && !obj.isPlayerControlled() && !containerNetworkIdForDatabase.isValid() && transformForDatabase.getPosition_p() != Vector::zero, ("Tried to send a non-origin persisted object position to the db in a space scene for non-player object %s", obj.getDebugInformation().c_str()));

	//Vector vp = transformForDatabase.getPosition_p();
	//Vector vw = obj.getTransform_o2w().getPosition_p();
	//LOG("PositionUpdateTracker",("sendPositionUpdate PS XYZ (%f %f %f)   WS XYZ (%f %f %f)",vp.x, vp.y, vp.z, vw.x, vw.y, vw.z));

	UpdateObjectPositionMessage const positionMessage(
		obj.getNetworkId(),
		transformForDatabase,
		worldspaceTransformForDatabase,
		containerNetworkIdForDatabase,
		objectArrangementForDatabase,
		loadWithId,
		obj.isPlayerControlled(),
		obj.asCreatureObject() ? true : false);

	GameServer::getInstance().sendToDatabaseServer(positionMessage);

	if (loadWithId != obj.getLoadWith())
	{
		obj.setLoadWith(loadWithId);
		Container * const container = ContainerInterface::getContainer(obj);
		if (container)
		{
			for (ContainerIterator j = container->begin(); j != container->end(); ++j)
			{
				ServerObject * const content = safe_cast<ServerObject *>((*j).getObject());
				if (content)
					sendPositionUpdate(*content);
			}
		}
	}
}
// ----------------------------------------------------------------------
void SpaceDockingManager::releaseDockingProcedure(NetworkId const & dockingUnit, NetworkId const & dockTarget)
{
	ShipsBeingDockedList::iterator iterShipsBeingDockedList = s_shipsBeingDockedList.find(CachedNetworkId(dockTarget));

	if (iterShipsBeingDockedList != s_shipsBeingDockedList.end())
	{
		// Remove the docking unit from the pad

		DockableShip & dockableShip = iterShipsBeingDockedList->second;
		DockPadList::iterator iterDockPadList = dockableShip.m_dockPadList.begin();
		bool foundUnit = false;

		for (; iterDockPadList != dockableShip.m_dockPadList.end(); ++iterDockPadList)
		{
			OccupantList::iterator iterOccupantList = iterDockPadList->m_occupantList.find(dockingUnit);

			if (iterOccupantList != iterDockPadList->m_occupantList.end())
			{
				LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("SpaceDockingManager::releaseDockingProcedure() dockingUnit(%s) dockTarget(%s) Removing unit from docking pad.", dockingUnit.getValueString().c_str(), dockTarget.getValueString().c_str()));

				iterDockPadList->m_occupantList.erase(iterOccupantList);
				foundUnit = true;
				break;
			}
		}

		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled() && !foundUnit, "debug_ai", ("SpaceDockingManager::releaseDockingProcedure() dockingUnit(%s) dockTarget(%s) Unable to find the dockingUnit on a dock pad.", dockingUnit.getValueString().c_str(), dockTarget.getValueString().c_str()));

		if (iterShipsBeingDockedList->second.getOccupantCount() <= 0)
		{
			// No more ships are using this ship to dock, stop tracking it

			s_shipsBeingDockedList.erase(iterShipsBeingDockedList);

			LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("SpaceDockingManager::releaseDockingProcedure() REMOVING dockTarget(%s) s_shipsBeingDockedList.size(%u)", dockTarget.getValueString().c_str(), s_shipsBeingDockedList.size()));
		}
	}
	else
	{
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "debug_ai", ("SpaceDockingManager::releaseDockingProcedure() Why is this dockTarget(%s) not in the ShipsBeingDockedList?", dockTarget.getValueString().c_str()));
	}
}
void ServerObject::updateContainment(NetworkId const &containerId, int slotArrangement)
{
	FATAL(isAuthoritative(), ("ServerObject::updateContainment: obj %s, container %s, arrangement %d, while auth", getDebugInformation().c_str(), containerId.getValueString().c_str(), slotArrangement));

	getContainedByProperty()->setContainedBy(containerId, false);
	ContainerInterface::getSlottedContainmentProperty(*this)->setCurrentArrangement(slotArrangement, false);
	ContainmentMessageManager::addContainmentMessage(*this);
}
Exemple #21
0
// ----------------------------------------------------------------------
void Squad::removeUnit(NetworkId const & unit)
{
	UnitMap::iterator iterUnitMap = m_unitMap->find(CachedNetworkId(unit));

	if (iterUnitMap != m_unitMap->end())
	{
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::removeUnit() className(%s) squadId(%d) unit(%s) squadSize(%d-1) leader(%s)", getClassName(), m_id, unit.getValueString().c_str(),  m_unitMap->size(), m_leader.getValueString().c_str()));

		bool const wasLeader = (iterUnitMap->first == m_leader);

		m_unitMap->erase(iterUnitMap);

		// See if we need to assign a new squad leader

		if (wasLeader)
		{
			bool const rebuildFormation = false;

		    if (!isEmpty())
			{
				IGNORE_RETURN(setLeader(m_unitMap->begin()->first, rebuildFormation));
			}
			else
			{
				IGNORE_RETURN(setLeader(NetworkId::cms_invalid, rebuildFormation));
			}
		}

		m_formation.markDirty();

		onRemoveUnit();
	}
	else
	{
#ifdef _DEBUG
		FormattedString<1024> fs;
		char const * const text = fs.sprintf("Squad::removeUnit() ERROR: className(%s) squadId(%d) Unable to find the unit(%s)", getClassName(), m_id, unit.getValueString().c_str());
		DEBUG_WARNING(true, (text));
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", (text));
#endif // _DEBUG
	}

//#ifdef _DEBUG
//	if (ConfigServerGame::isSpaceAiLoggingEnabled())
//	{
//		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::removeUnit() squadId(%d) newSize(%u)", m_id, m_unitMap->size()));
//		iterUnitMap = m_unitMap->begin();
//		int index = 1;
//
//		for (; iterUnitMap != m_unitMap->end(); ++iterUnitMap)
//		{
//			LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::removeUnit() squadId(%d) [%2d] unit(%s)", m_id, index, iterUnitMap->getValueString().c_str()));
//			++index;
//		}
//	}
//#endif // _DEBUG
}
void SwgSnapshot::decodeQuests(NetworkId const & networkId, Archive::ReadIterator &data, 
	DB::BufferString &part1, DB::BufferString &part2,
	DB::BufferString &part3, DB::BufferString &part4) const
{

	const int ki_num_parts = 4;
	const int ki_chunk_size = DBSchema::PlayerObjectRow::QUEST_DATA_SIZE;
	static const std::string space(" ");

	std::string packedValue;
	Archive::AutoDeltaPackedMap<uint32,PlayerQuestData>::unpack(data,packedValue);

	if (packedValue.length() > ki_chunk_size * ki_num_parts)
		{
			// Remove completed quests to save space.  This is a last-ditch effort to save a crash, not a good way to
			// handle it.
			
			WARNING(true,("QuestData:  Object %s had too much quest data to be stored in the database.  Truncating.",networkId.getValueString().c_str()));
		int charsToRemove = packedValue.length() - ki_chunk_size * ki_num_parts;
			char const * sourcePos = packedValue.c_str();
			std::string newPackedValue;
			bool activeQuest=false;
			char entry[100];
			char * entryPos = entry;
			while (charsToRemove > 0 && *sourcePos != '\0')
			{
				*(entryPos++)=*sourcePos;

				if (*sourcePos==' ')
					activeQuest=true;
				if (*(sourcePos++)==':')
				{
					if (activeQuest)
					{
						// copy this active quest
						*entryPos='\0';
						newPackedValue+=entry;
						entryPos=entry;
						activeQuest=false;
					}
					else
					{
						// don't copy this completed quest
						charsToRemove -= entryPos-entry;
						entryPos=entry;
					}
				}					
			}
			packedValue = newPackedValue + sourcePos;
		}


	part1=std::string(packedValue,0,ki_chunk_size);

	// part2
	if (packedValue.length() > ki_chunk_size * 1) 
		part2=std::string(packedValue, ki_chunk_size * 1, ki_chunk_size);
	else
		part2=space;

	// part3
	if (packedValue.length() > ki_chunk_size * 2) 
		part3=std::string(packedValue, ki_chunk_size * 2, ki_chunk_size);
	else
		part3=space;

	// part4
	if (packedValue.length() > ki_chunk_size * 3) 
		part4=std::string(packedValue, ki_chunk_size * 3, ki_chunk_size);
	else
		part4=space;
	}
Exemple #23
0
// ----------------------------------------------------------------------
void Squad::addUnit(NetworkId const & unit)
{
	// If this unit is the only unit in the squad, it is assigned as the squad leader

	UnitMap::const_iterator iterUnitMap = m_unitMap->find(CachedNetworkId(unit));

	if (iterUnitMap == m_unitMap->end())
	{
		bool const leader = m_unitMap->empty();

		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::addUnit() className(%s) squadId(%d) unit(%s) leader(%s) squadSize(%d+1)", getClassName(), m_id, unit.getValueString().c_str(), leader ? "yes" : "no", m_unitMap->size()));

		//-- Add the unit to the new squad

		IGNORE_RETURN(m_unitMap->insert(std::make_pair(CachedNetworkId(unit), &PersistentCrcString::empty)));

		if (leader)
		{
			bool const rebuildFormation = true;
			IGNORE_RETURN(setLeader(unit, rebuildFormation));
		}

		m_formation.markDirty();

		onAddUnit(unit);
	}
	else
	{
#ifdef _DEBUG
		FormattedString<1024> fs;
		char const * const text = fs.sprintf("Squad::addUnit() className(%s) squadId(%d) unit(%s) is already in the squad, not re-adding", getClassName(), m_id, unit.getValueString().c_str());
		DEBUG_WARNING(true, (text));
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", (text));
#endif // _DEBUG
	}

//#ifdef _DEBUG
//	if (ConfigServerGame::isSpaceAiLoggingEnabled())
//	{
//		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::addUnit() squadId(%d) newSize(%u)", m_id, m_unitMap->size()));
//		iterUnitMap = m_unitMap->begin();
//		int index = 1;
//
//		for (; iterUnitMap != m_unitMap->end(); ++iterUnitMap)
//		{
//			LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::addUnit() squadId(%d) [%2d] unit(%s)", m_id, index, iterUnitMap->getValueString().c_str()));
//			++index;
//		}
//	}
//#endif // _DEBUG
}
void PlanetProxyObject::removeContainedObject(const NetworkId &theObject)
{
	if (!m_contents)
	{
		WARNING(true,("Attempted to remove object %s from object %s, but that object has no contents.", theObject.getValueString().c_str(), m_objectId.getValueString().c_str()));
		return;
	}
	std::vector<NetworkId>::iterator newEnd=std::remove(m_contents->begin(), m_contents->end(), theObject);
	if (newEnd==m_contents->end())
	{
		WARNING(true,("Attempted to remove object %s from object %s, but it was not in the container.", theObject.getValueString().c_str(), m_objectId.getValueString().c_str()));
		return;
	}
	m_contents->erase(newEnd, m_contents->end());
}
Exemple #25
0
// ----------------------------------------------------------------------
bool Squad::setLeader(NetworkId const & unit, bool const rebuildFormation)
{
	LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", ("Squad::setLeader() className(%s) squadId(%d) unit(%s) rebuildFormation(%s)", getClassName(), m_id, unit.getValueString().c_str(), rebuildFormation ? "yes" : "no"));

	if (   isEmpty()
	    && (unit == NetworkId::cms_invalid))
	{
		m_leader = CachedNetworkId::cms_cachedInvalid;

		return true;
	}

	bool result = false;
	UnitMap::iterator iterUnitMap = m_unitMap->find(CachedNetworkId(unit));

	if (iterUnitMap != m_unitMap->end())
	{
		result = true;

		NetworkId oldLeader(m_leader);
		m_leader = CachedNetworkId(unit);
		onNewLeader(oldLeader);

		if (rebuildFormation)
		{
			m_formation.markDirty();
		}
	}
	else
	{
		m_leader = CachedNetworkId::cms_cachedInvalid;

#ifdef _DEBUG
		FormattedString<1024> fs;
		char const * const text = fs.sprintf("Squad::setLeader() ERROR: className(%s) Trying to set a leader(%s) who is not a member of the squad.", getClassName(), unit.getValueString().c_str());
		DEBUG_WARNING(true, (text));
		LOGC(ConfigServerGame::isSpaceAiLoggingEnabled(), "space_debug_ai", (text));
#endif // _DEBUG
	}

	return result;
}
/**
 * Retreive a range of attributes for an object
 */
void CreatureObjectBuffer::getAttributesForObject(const NetworkId &objectId, std::vector<Attributes::Value> &values, int offset, int howMany) const
{
	const DBSchema::CreatureObjectBufferRow *row=dynamic_cast<const DBSchema::CreatureObjectBufferRow*>(findConstRowByIndex(objectId));

	for (int position=offset; position<offset+howMany; ++position)
	{
		int value=0;
		switch(position)
		{
			case 0:
				row->attribute_0.getValue(value);
				break;
			case 1:
				row->attribute_1.getValue(value);
				break;
			case 2:
				row->attribute_2.getValue(value);
				break;
			case 3:
				row->attribute_3.getValue(value);
				break;
			case 4:
				row->attribute_4.getValue(value);
				break;
			case 5:
				row->attribute_5.getValue(value);
				break;
			case 6:
				row->attribute_6.getValue(value);
				break;
			case 7:
				row->attribute_7.getValue(value);
				break;
			case 8:
				row->attribute_8.getValue(value);
				break;
			case 9:
				row->attribute_9.getValue(value);
				break;
			case 10:
				row->attribute_10.getValue(value);
				break;
			case 11:
				row->attribute_11.getValue(value);
				break;
			case 12:
				row->attribute_12.getValue(value);
				break;
			case 13:
				row->attribute_13.getValue(value);
				break;
			case 14:
				row->attribute_14.getValue(value);
				break;
			case 15:
				row->attribute_15.getValue(value);
				break;
			case 16:
				row->attribute_16.getValue(value);
				break;
			case 17:
				row->attribute_17.getValue(value);
				break;
			case 18:
				row->attribute_18.getValue(value);
				break;
			case 19:
				row->attribute_19.getValue(value);
				break;
			case 20:
				row->attribute_20.getValue(value);
				break;
			case 21:
				row->attribute_21.getValue(value);
				break;
			case 22:
				row->attribute_22.getValue(value);
				break;
			case 23:
				row->attribute_23.getValue(value);
				break;
			case 24:
				row->attribute_24.getValue(value);
				break;
			case 25:
				row->attribute_25.getValue(value);
				break;
			case 26:
				row->attribute_26.getValue(value);
				break;

			default:
				FATAL(true,("Programmer bug:  getAttributesForObject(%s, &values, %i, %i):  attempted to read attribute %i, which is out of range",objectId.getValueString().c_str(),offset, howMany, position));
			}
		if (value == -999)
		{
			WARNING(true,("Object %s had null attribute %i, defaulting to 100",objectId.getValueString().c_str(), position));
			value = 100;
		}
		
		values.push_back(static_cast<Attributes::Value>(value));
	}
}