void CreatureObject::makePetMountable()
{
	//-- Ensure mounts are enabled.
	if (!ConfigServerGame::getMountsEnabled())
	{
		LOG(cs_mountInfoChannelName, ("CreatureObject::makePetMountable() called on object id=[%s] when mounts are disabled, ignoring call.", getNetworkId().getValueString().c_str()));
		return;
	}
	
	//-- Validate preconditions.
	DEBUG_FATAL(!isAuthoritative(), ("makePetMountable(): called on non-authoritative creature id=[%s],template=[%s].", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
	DEBUG_FATAL(getMountabilityStatus() != static_cast<int>(MountValidScaleRangeTable::MS_creatureMountable), ("makePetMountable(): creature id=[%s],template=[%s] this creature cannot be made mountable. Caller should have checked getMountabilityStatus() first.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
	DEBUG_FATAL(isMountable(), ("makePetMountable(): creature id=[%s],template=[%s] already is mountable.  Caller doesn't need to call makePetMountable().", getNetworkId().getValueString().c_str(), getObjectTemplateName()));

	//-- Get the pet control device network id.
	NetworkId const pcdNetworkId = getPetControlDeviceId();
	if (!pcdNetworkId.isValid())
	{
		DEBUG_FATAL(true, ("makePetMountable(): creature id=[%s],template=[%s] does not have a valid pet control device id on it. Expecting script to place this objvar on the pet.", getNetworkId().getValueString().c_str(), getObjectTemplateName()));
		return;
	}

	//-- Set the Condition bit to indicate we're a mount.
	setCondition(getCondition() | static_cast<int>(ServerTangibleObjectTemplate::C_mount));

	//-- Set the Creature as static so that it doesn't count against the spawn limit.
	setIsStatic(true);
}
Beispiel #2
0
void NickView::startQuery(const QModelIndex &index)
{
    if (index.data(NetworkModel::ItemTypeRole) != NetworkModel::IrcUserItemType)
        return;

    IrcUser *ircUser = qobject_cast<IrcUser *>(index.data(NetworkModel::IrcUserRole).value<QObject *>());
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!ircUser || !networkId.isValid())
        return;

    Client::bufferModel()->switchToOrStartQuery(networkId, ircUser->nick());
}
BufferId NetworkModelController::findQueryBuffer(const QModelIndex &index, const QString &predefinedNick) const
{
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!networkId.isValid())
        return BufferId();

    QString nick = predefinedNick.isEmpty() ? nickName(index) : predefinedNick;
    if (nick.isEmpty())
        return BufferId();

    return findQueryBuffer(networkId, nick);
}
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 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));
	}
}
AiLocation::AiLocation ( NetworkId const & cellId, Vector const & position, float radius )
:	m_valid(true),
	m_attached(false),
	m_object(NULL),
	m_objectId(),
	m_cellObject(NULL),
	m_position_p(position),
	m_position_w(position),
	m_radius(radius),
	m_offset_p(Vector::zero),
	m_relativeOffset(false),
	m_hasChanged(true),
	m_cuttable(true),
	m_debugId(gs_debugCounter++)
{
	if(cellId.isValid())
	{
		m_cellObject = NetworkIdManager::getObjectById(cellId);
	}
	else
	{
		m_cellObject = &CellProperty::getWorldCellProperty()->getOwner();
	}

	if(m_cellObject)
	{
		m_position_w = CollisionUtils::transformToWorld(m_cellObject->getCellProperty(),m_position_p);
	}

	VALIDATE_LOCATION();
}
void ContextMenuActionProvider::addNetworkItemActions(QMenu *menu, const QModelIndex &index)
{
    NetworkId networkId = index.data(NetworkModel::NetworkIdRole).value<NetworkId>();
    if (!networkId.isValid())
        return;
    const Network *network = Client::network(networkId);
    Q_CHECK_PTR(network);
    if (!network)
        return;

    addAction(NetworkConnect, menu, network->connectionState() == Network::Disconnected);
    addAction(NetworkDisconnect, menu, network->connectionState() != Network::Disconnected);
    menu->addSeparator();
    addAction(ShowChannelList, menu, index, ActiveState);
    addAction(JoinChannel, menu, index, ActiveState);
}
void ToolBarActionProvider::networkCreated(NetworkId id) {
  const Network *net = Client::network(id);
  Action *act = new Action(net->networkName(), this);
  _networkActions[id] = act;
  act->setObjectName(QString("NetworkAction-%1").arg(id.toInt()));
  act->setData(QVariant::fromValue<NetworkId>(id));
  connect(net, SIGNAL(updatedRemotely()), SLOT(networkUpdated()));
  connect(act, SIGNAL(triggered()), SLOT(connectOrDisconnectNet()));
  networkUpdated(net);
}
jlong JNICALL ScriptMethodsMountNamespace::getRiderId(JNIEnv *env, jobject self, jlong mountId)
{
	UNREF(env);
	UNREF(self);

	//-- Ignore calls if mounts are disabled.
	if (!ConfigServerGame::getMountsEnabled())
		return 0;

	//-- Get the rider object.
	bool const throwIfNotOnServer = false;
	CreatureObject const *const mountObject = JavaLibrary::getCreatureThrow(env, mountId, "getRiderId(): error in mountId arg", throwIfNotOnServer);
	if (!mountObject)
		return 0;

	CreatureObject const *const riderObject = mountObject->getPrimaryMountingRider();
	NetworkId const riderNetworkId = (riderObject ? riderObject->getNetworkId() : NetworkId::cms_invalid);

	return riderNetworkId.getValue();
}
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 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);
}
bool ConsoleCommandParser::performParsing(const NetworkId & track, const StringVector_t & argv, const String_t &, String_t & result, const CommandParser *)
{
	bool successResult = false;

	if(isCommand(argv[0], "transfer"))
	{
		if(isCommand(argv[1], "requestMove"))
		{
			if(argv.size() > 5)
			{
				std::string stationIdString = Unicode::wideToNarrow(argv[2]);
				std::string characterName = Unicode::wideToNarrow(argv[3]);
				std::string sourceServer = Unicode::wideToNarrow(argv[4]);
				std::string destinationServer = Unicode::wideToNarrow(argv[5]);
				
				LOG("CustomerService", ("CharacterTransfer: received console request to transfer %s, belonging to %s from %s to %s", characterName.c_str(), stationIdString.c_str(), sourceServer.c_str(), destinationServer.c_str()));

				result += Unicode::narrowToWide("Received request to move ");
				result += Unicode::narrowToWide(characterName);
				result += Unicode::narrowToWide(" owned by station ID ");
				result += Unicode::narrowToWide(stationIdString);
				result += Unicode::narrowToWide(" on cluster ");
				result += Unicode::narrowToWide(sourceServer);
				result += Unicode::narrowToWide(" to cluster ");
				result += Unicode::narrowToWide(destinationServer);

				const unsigned int stationId = static_cast<const unsigned int>(atoi (stationIdString.c_str()));
				const unsigned int trackId = static_cast<const unsigned int>(track.getValue());

				//todo : drive these through the command handler, just testing
				// basic functionality for now.
				const bool withItems = true;
				const bool allowOverride = true;
				
				TransferServer::requestMove(trackId, "en", sourceServer, destinationServer, characterName, characterName, stationId, stationId, trackId, withItems, allowOverride);
				successResult = true;
			}
			else
			{
				std::string messageString = "not enough arguments to 'requestMove <station id> <character name> <source server> <destination server>'";
				StringVector_t::const_iterator i;
				
				for(i = argv.begin(); i != argv.end(); ++i)
				{
					messageString = messageString + Unicode::wideToNarrow(*i) + " | ";
				}
				LOG("CustomerService", ("CharacterTransfer: %s", messageString.c_str()));
				result += Unicode::narrowToWide(messageString);
			}
		}
		else if (isCommand(argv[1], "requestAccountMove"))
		{
			if (argv.size() > 3)
			{
				std::string sourceStationIdString      = Unicode::wideToNarrow(argv[2]);
				std::string destinationStationIdString = Unicode::wideToNarrow(argv[3]);

				LOG("CustomerService", ("CharacterTransfer: received console request to transfer account from station ID %s to station ID %s", sourceStationIdString.c_str(), destinationStationIdString.c_str()));

				result += Unicode::narrowToWide("Received request to move from station ID ");
				result += Unicode::narrowToWide(sourceStationIdString);
				result += Unicode::narrowToWide(" to station ID ");
				result += Unicode::narrowToWide(destinationStationIdString);
				result += Unicode::narrowToWide("\n");

				const unsigned int sourceStationId      = static_cast<const unsigned int>(atoi (sourceStationIdString.c_str()));
				const unsigned int destinationStationId = static_cast<const unsigned int>(atoi (destinationStationIdString.c_str()));
				const unsigned int trackId              = static_cast<const unsigned int>(track.getValue());

				TransferServer::requestTransferAccount(trackId, sourceStationId, destinationStationId, trackId);
				successResult = true;
			}
			else
			{
				std::string messageString = "not enough arguments to 'requestAccountMove <source station id> <destination station id>'";
				StringVector_t::const_iterator i;
				
				for(i = argv.begin(); i != argv.end(); ++i)
				{
					messageString = messageString + Unicode::wideToNarrow(*i) + " | ";
				}
				LOG("CustomerService", ("CharacterTransfer: %s\n", messageString.c_str()));
				result += Unicode::narrowToWide(messageString);
				result += Unicode::narrowToWide("\n");
			}
		}
	}
		
	return successResult;
}
// ----------------------------------------------------------------------
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 put(ByteStream & target, const NetworkId & source)
	{
		//uint64 tmp = source.getValue();
		put(target, source.getValue());
		//target.put(&tmp,8);
	}
/**
 * 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 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()));
	}
}
/**
 * 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);
	}
}
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());
}
Beispiel #20
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 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 AiLocation::unpack( Archive::ReadIterator & source )
{
	Archive::get(source, m_valid);
	Archive::get(source, m_attached);
	Archive::get(source, m_relativeOffset);
	Archive::get(source, m_hasChanged);
	Archive::get(source, m_cuttable);
	Archive::get(source, m_debugId);
	Archive::get(source, m_radius);

	uint8 package;
	Archive::get(source, package);
	switch (static_cast<AiLocationArchive::AiLocationPackage>(package))
	{
		case AiLocationArchive::ALP_None:
			// do nothing
			break;
		case AiLocationArchive::ALP_Cell:
			{
				NetworkId cellId;
				Archive::get(source, cellId);
				Archive::get(source, m_position_p);
				m_position_w = m_position_p;
				if (cellId.isValid())
				{
					m_cellObject = NetworkIdManager::getObjectById(cellId);
				}
				else
				{
					m_cellObject = &CellProperty::getWorldCellProperty()->getOwner();
				}

				if (m_cellObject)
				{
					m_position_w = CollisionUtils::transformToWorld(m_cellObject->getCellProperty(),m_position_p);
				}
			}
			break;
		case AiLocationArchive::ALP_World:
			{
				Archive::get(source, m_position_w);
				m_position_p = m_position_w;
			}
			break;
		case AiLocationArchive::ALP_Object:
			{
				NetworkId objectId;
				Archive::get(source, objectId);
				setObject(NetworkIdManager::getObjectById(objectId));
			}
			break;
		case AiLocationArchive::ALP_OffsetObject:
			{
				NetworkId objectId;
				Archive::get(source, objectId);
				Archive::get(source, m_offset_p);
				setObject(NetworkIdManager::getObjectById(objectId));
			}
			break;
		default:
			WARNING(true, ("AiLocation::AiLocation(archive) received unknown data "
				"type %d", static_cast<int>(package)));
			break;
	}
	
	VALIDATE_LOCATION();	
}
// ----------------------------------------------------------------------
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();
}
Beispiel #24
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())));
}
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);
}
bool ConsoleCommandParserGame::performParsing(const NetworkId & track, const StringVector_t & argv,const String_t & originalCommand,String_t & result,const CommandParser *)
{
	bool successResult = false;

	if(isCommand(argv[0], CommandNames::game))
	{
		if(argv.size() > 1)
		{
			std::string cmd = Unicode::wideToNarrow(argv[1]);
			if(cmd == "any")
			{
				// grab a random game server to execute this command
				GameServerConnection * gameConn = CentralServer::getInstance().getRandomGameServer();
				if(gameConn)
				{
					ConGenericMessage cm(Unicode::wideToNarrow(originalCommand), static_cast<unsigned int>(track.getValue()));
					gameConn->send(cm, true);
					successResult = true;
				}
				else
				{
					result += Unicode::narrowToWide("No game servers available to service request");
					ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
				}

			}
			else if(cmd == "kill")
			{
				// kill the game server process specified (by disconnecting it from central)
				if(argv.size() > 2)
				{
					unsigned int pid;
					sscanf(Unicode::wideToNarrow(argv[2]).c_str(), "%d", &pid);
					GameServerConnection * gameConn = CentralServer::getInstance().getGameServer(pid);
					if(gameConn)
					{
						gameConn->setDisconnectReason("Central ConsoleCommandParserGame kill command");
						gameConn->disconnect();
						successResult = true;
						ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));

					}
				}
			}
			else if(cmd == "enumerate")
			{
				std::vector<const GameServerConnection *> gameServers = CentralServer::getInstance().getGameServers();
				std::vector<const GameServerConnection *>::const_iterator i;
				for(i = gameServers.begin(); i != gameServers.end(); ++i)
				{
					char entry[256] = {"\0"};
					IGNORE_RETURN(snprintf(entry, sizeof(entry), "%lu, %lu, %s, %s\n", (*i)->getProcessId(), (*i)->getOsProcessId(), (*i)->getRemoteAddress().c_str(), (*i)->getSceneId().c_str()));
					result += Unicode::narrowToWide(entry);
				}
				ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
			}
			else if( cmd == "abortShutdown" )
			{
				LOG("ServerConsole", ("Received command to abort the current shutdown sequence."));
				CentralServer::getInstance().abortShutdownProcess();
				result += Unicode::narrowToWide("Instructing Central Server to abort shutdown sequence.\n");
				successResult = true;
				ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
			}
			// starts the shutdown process
			else if(cmd == "shutdown")
			{
				if( argv.size() > 4 )
				{
					LOG("ServerConsole", ("Received command to shutdown the cluster."));
					uint32 timeToShutdown = strtoul(Unicode::wideToNarrow(argv[2]).c_str(), NULL, 10);
					uint32 maxTime = strtoul(Unicode::wideToNarrow(argv[3]).c_str(), NULL, 10);
					Unicode::String systemMessage = Unicode::narrowToWide("");
					for(unsigned int i = 4; i < argv.size(); ++i)
					{
						systemMessage += argv[i] + Unicode::narrowToWide(" ");
					}
					CentralServer::getInstance().startShutdownProcess(timeToShutdown, maxTime, systemMessage);
					result += Unicode::narrowToWide("Instructing Central Server to begin shutdown sequence.\n");
					successResult = true;
					ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
				}
				// failed to provide enough parameters
				else
				{
					LOG("ServerConsole", ("Received an improperly formatted shutdown command."));
					result += Unicode::narrowToWide("Not enough parameters specified. Usage is \"game shutdown <time to shutdown in seconds> <max time to wait in seconds> <system broadcast message>\"\n");
					ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
				}
			}
			else if(cmd == "authorizeTransfer")
			{
				if(argv.size() > 1)
				{
					unsigned int stationId = strtoul(Unicode::wideToNarrow(argv[2]).c_str(), NULL, 10);
					if(stationId > 0)
					{
						GenericValueTypeMessage<unsigned int> auth("AuthorizeDownload", stationId);
						CentralServer::getInstance().sendToTransferServer(auth);
						result += Unicode::narrowToWide("sent authorization request");
					}
				}
				ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
			}
			else if(cmd == "requestMove")
			{
				if(argv.size() > 5)
				{
					ConGenericMessage cm(Unicode::wideToNarrow(originalCommand), static_cast<unsigned int>(track.getValue()));
					CentralServer::getInstance().sendToTransferServer(cm);
				}
			}
			else
			{
				if(! isalpha(cmd.c_str()[0]))
				{
					// check to see if the next parameter is a pid to send the command to
					uint32 pid;
					sscanf(Unicode::wideToNarrow(argv[1]).c_str(), "%lu", &pid);
					GameServerConnection * gameConn = CentralServer::getInstance().getGameServer(pid);
					if(gameConn)
					{
						ConGenericMessage cm(Unicode::wideToNarrow(originalCommand), static_cast<unsigned int>(track.getValue()));
						gameConn->send(cm, true);
						successResult = true;
					}
					else
					{
						result += Unicode::narrowToWide("No game servers available to service request");
						ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
					}
				}
				else
				{
					// a planet 
					GameServerConnection * gameConn = CentralServer::getInstance().getGameServer(Unicode::wideToNarrow(argv[1]));
					if(gameConn)
					{
						ConGenericMessage cm(Unicode::wideToNarrow(originalCommand), static_cast<unsigned int>(track.getValue()));
						gameConn->send(cm, true);
						successResult = true;
					}
					else
					{
						result += Unicode::narrowToWide("No game servers available to service request");
						ConsoleConnection::onCommandComplete(Unicode::wideToNarrow(result), static_cast<int>(track.getValue()));
					}
				}
			}
		}
		else
		{
			// select a game server to execute this command
			result += Unicode::narrowToWide("insufficient arguments");
			successResult = true;
		}
	}

	return successResult;
}
Beispiel #27
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 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;
}
Beispiel #29
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;
}
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);
			}
		}
	}
}