Пример #1
0
void WorldManager::removePlayerfromAccountMap(uint64 playerID)
{
	CreatureObject* creature = dynamic_cast<CreatureObject*>(gWorldManager->getObjectById(playerID));
	if(!creature)	{
		LOG (error) << "WorldManager::removePlayerfromAccountMap : no player";
		return;
	}

	PlayerObject* player = creature->GetGhost();

    if(player)    {
        PlayerAccMap::iterator playerAccIt = mPlayerAccMap.find(player->getAccountId());

        if(playerAccIt != mPlayerAccMap.end())        {
            LOG(info) << "Player left [" << player->getId() << "] Total players on zone [" << (getPlayerAccMap()->size() -1) << "]";
            mPlayerAccMap.erase(playerAccIt);
        }
        else
        {
            LOG(error) << "Error removing player from account map [" << player->getAccountId() << "]";
        }
    }
    else
    {
        LOG(error) << "Error removing player from account map [" << player->getAccountId() << "]";
    }
}
Пример #2
0
void ObjectController::_handleDismissGroupMember(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // make sure its a fully grouped player
    if(player->getGroupId() == 0)
    {
        return;
    }

    // lets get the target player
    message->setIndex(32);
    PlayerObject* targetPlayer = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(message->getUint64()));


    // if  target is valid
    if(targetPlayer == NULL || targetPlayer->getGroupId() != player->getGroupId())
    {
        gMessageLib->sendSystemMessage(player,L"Invalid Target.");
        return;
    }

    // we advise the chat server about it
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupDismissGroupMember);
    gMessageFactory->addUint32(targetPlayer->getAccountId());
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #3
0
bool WorldManager::_handleDisconnectUpdate(uint64 callTime,void* ref)
{
    PlayerList::iterator it = mPlayersToRemove.begin();

    while(it != mPlayersToRemove.end())
    {
        PlayerObject* playerObject = (*it);

        // we timed out, so save + remove it
        if(--*(playerObject->getDisconnectTime()) <= 0 && playerObject->isLinkDead())
        {
            // reset link dead state
            playerObject->togglePlayerFlagOff(PlayerFlag_LinkDead);
            playerObject->setConnectionState(PlayerConnState_Destroying);

			//remove the player out of his group - if any
			GroupObject* group = gGroupManager->getGroupObject(playerObject->getGroupId());
			if(group)
			{
				group->removePlayer(playerObject->getId());
			}

            //asynch save
            savePlayer(playerObject->getAccountId(),true,WMLogOut_LogOut);

            it = mPlayersToRemove.erase(it);
        }
        else
            ++it;

    }

    return(true);
}
Пример #4
0
void ObjectController::broadcastGalaxyMessage(BString theBroadcast, int32 planetId) const
{
    if (theBroadcast.getLength())
    {
        PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);
        if (player)
        {
            theBroadcast.convert(BSTRType_Unicode16);

            // let the chatserver handle this.
            Message* newMessage;
            gMessageFactory->StartMessage();
            gMessageFactory->addUint32(opIsmBroadcastGalaxy);
            gMessageFactory->addUint32(planetId);
            gMessageFactory->addString(theBroadcast);
            newMessage = gMessageFactory->EndMessage();
            player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
            //this should be fastpath as not being Mission critical and we want to prevent the communication protocol overhead with Acks and resends

            // Convert since we are going to print it.
            // theBroadcast.convert(BSTRType_ANSI);
        }
    }

}
Пример #5
0
void ObjectController::_handleGroupChat(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    string msgText;

    msgText.setType(BSTRType_Unicode16);
    msgText.setLength(512);

    //Honey bunnies!
    //this is like all handled by the Objectcontroller???
    //we just have to look at the Message here !!!!!!!!

    //gLogger->hexDump always shows the complete Message!!!!! the Objectcontroller however sets the Index to the first data
    //byte AFTER the Objectcontroller header has been dealt with !

    /*
    data32 = message->getUint32();	// object controller opcode
    data32 = message->getUint32();	// Unknown
    data32 = message->getUint32();	// command enqueue
    playerId = message->getUint64();// player id
    data32 = message->getUint32();	// Unknown
    uint32 requestId = message->getUint32();	// RequestID
    // data32 = message->getUint32();	// Unknown RequestID?????
    data32 = message->getUint32();	// command crc (crc of "groupchat")
    data64 = message->getUint64();	// empty id field
    */
    message->getStringUnicode16(msgText);	// unicode string

    // make sure its a fully grouped player
    if (!player)
    {
        gLogger->logMsg("ObjectController::_handleGroupChat NO PLAYER\n");
    }

    if(!player->getGroupId())
    {

        gLogger->logMsg("ObjectController::_handleGroupChat NO GROUP");
    }

    // let the chatserver handle this.
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupSay);
    gMessageFactory->addUint32(0);
    gMessageFactory->addString(msgText);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
    //this should be fastpath as not being Mission critical and we want to prevent the communication protocol overhead with Acks and resends

    // Convert since we are going to print it.
    // msgText.convert(BSTRType_ANSI);
}
void ObjectController::_handlefindfriend(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
	PlayerObject*	playerObject	= dynamic_cast<PlayerObject*>(mObject);
	string			friendName;
	int8			sql[1024],end[16],*sqlPointer;

	message->getStringUnicode16(friendName);

	if(!friendName.getLength())
	{
		gMessageLib->sendSystemMessage(playerObject,L"","ui_cmnty","friend_location_failed_usage","","",L"",0,"","",L"");
		return;
	}
	
	if(playerObject->isConnected())
	{
		// query the chat server
		gMessageFactory->StartMessage();
		gMessageFactory->addUint32(opNotifyChatFindFriend);
		gMessageFactory->addString(friendName);
		Message* message = gMessageFactory->EndMessage();

		playerObject->getClient()->SendChannelA(message,playerObject->getAccountId(),CR_Chat,2);
		
	}
	return;


	string unicodeName = friendName;
	friendName.convert(BSTRType_ANSI);


	// check if he's our friend
	if(!playerObject->checkFriendList(friendName.getCrc()))
	{
		gMessageLib->sendSystemMessage(playerObject,L"","cmnty","friend_not_found","","",L"",0,"","",unicodeName.getUnicode16());
		return;
	}

	
	// pull the db query
	ObjControllerAsyncContainer* asyncContainer = new(mDBAsyncContainerPool.malloc()) ObjControllerAsyncContainer(OCQuery_FindFriend);
	asyncContainer->mString = friendName.getAnsi();

	sprintf(sql,"SELECT id from swganh.characters where firstname like '");
	sprintf(end,"'");
	sqlPointer = sql + strlen(sql);
	sqlPointer += mDatabase->Escape_String(sqlPointer,friendName.getAnsi(),friendName.getLength());
	strcat(sql,end);

	mDatabase->ExecuteSqlAsync(this,asyncContainer,sql);

	
}
Пример #7
0
void ObjectController::_handleUninvite(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // lets get the target player
    message->setIndex(32);
    PlayerObject* targetPlayer = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(message->getUint64()));


    // if  target is valid
    if(targetPlayer == NULL || targetPlayer == player)
    {
        gMessageLib->sendSystemMessage(player,L"","group","uninvite_no_target_self");
        return;
    }

    // we advise the chat server
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupUnInvite);
    gMessageFactory->addUint32(targetPlayer->getAccountId());
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #8
0
void ObjectController::_handleDisband(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    if(player->getGroupId() == 0)
    {
        return;
    }

    // we advise the chat server about the disband
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupDisband);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #9
0
void ObjectController::_handleJoin(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // resetting the sender's id
    gMessageLib->sendInviteSenderUpdateDeltasCreo6(0,player);

    // we advise the chat server that he accepted
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupInviteResponse);
    gMessageFactory->addUint8(1);
    gMessageFactory->addFloat(player->mPosition.x);
    gMessageFactory->addFloat(player->mPosition.z);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
void ObjectController::_handleAddIgnoreDBReply(uint32 retCode,string ignoreName)
{
	
	PlayerObject*	player	= dynamic_cast<PlayerObject*>(mObject);

	// gLogger->logMsgF("_handleAddIgnoreDBReply retCode = %u",MSG_NORMAL, retCode);

	switch(retCode)
	{
		// no such name
		case 0:
		default:
		{
			ignoreName.convert(BSTRType_Unicode16);
			gMessageLib->sendSystemMessage(player,L"","cmnty","ignore_not_found","","",L"",0,"","",ignoreName.getUnicode16());
		}
		break;

		// add ok
		case 1:
		{
			// update list
			player->addIgnore(ignoreName.getAnsi());
			gMessageLib->sendIgnoreListPlay9(player);

			// send notification
			ignoreName.convert(BSTRType_Unicode16);
			gMessageLib->sendSystemMessage(player,L"","cmnty","ignore_added","","",L"",0,"","",ignoreName.getUnicode16());

			// notify chat server
			if(player->isConnected())
			{
				gMessageFactory->StartMessage();
				gMessageFactory->addUint32(opNotifyChatAddIgnore);
				gMessageFactory->addString(ignoreName);
				Message* message = gMessageFactory->EndMessage();

				player->getClient()->SendChannelA(message,player->getAccountId(),CR_Chat,2);
			}
		}
		break;
	}

	player->setContactListUpdatePending(false);
}
Пример #11
0
void ObjectController::_handleDecline(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // resetting the sender's id
    gMessageLib->sendInviteSenderUpdateDeltasCreo6(0,player);

    gMessageLib->sendSystemMessage(player, L"","group","decline_self");

    // we advise the chat server that he refused
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupInviteResponse);
    gMessageFactory->addUint8(0);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
    player->setGroupId(0);
}
Пример #12
0
void ObjectController::cancelScheduledShutdown(BString cancelShutdownReason) const
{
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);
    if (player)
    {
        cancelShutdownReason.convert(BSTRType_Unicode16);

        // let the chatserver handle this.
        Message* newMessage;
        gMessageFactory->StartMessage();
        gMessageFactory->addUint32(opIsmCancelShutdown);
        gMessageFactory->addUint32(0);					// Can be used as an option in the future,
        gMessageFactory->addString(cancelShutdownReason);
        newMessage = gMessageFactory->EndMessage();
        player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
        //this should be fastpath as not being Mission critical and we want to prevent the communication protocol overhead with Acks and resends
    }
}
void ObjectController::_handleRemoveFriendDBReply(uint32 retCode,string friendName)
{
	PlayerObject*	player	= dynamic_cast<PlayerObject*>(mObject);

	switch(retCode)
	{
		// no such name
		case 0:
		default:
		{
			friendName.convert(BSTRType_Unicode16);
			gMessageLib->sendSystemMessage(player,L"","cmnty","friend_not_found","","",L"",0,"","",friendName.getUnicode16());
		}
		break;

		// remove ok
		case 1:
		{
			// update list
			player->removeFriend(friendName.getCrc());
			gMessageLib->sendFriendListPlay9(player);

			// send notification
			friendName.convert(BSTRType_Unicode16);
			gMessageLib->sendSystemMessage(player,L"","cmnty","friend_removed","","",L"",0,"","",friendName.getUnicode16());

			if(player->isConnected())
			{
				// notify chat server
				gMessageFactory->StartMessage();
				gMessageFactory->addUint32(opNotifyChatRemoveFriend);
				gMessageFactory->addString(friendName);
				Message* message = gMessageFactory->EndMessage();

				player->getClient()->SendChannelA(message,player->getAccountId(),CR_Chat,2);
			}
		}
		break;
	}

	player->setContactListUpdatePending(false);
}
Пример #14
0
void ObjectController::_handleGroupLootMode(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    // disabled for now
    //return;

    gLogger->logMsg("_handleGroupLootMode");
    PlayerObject* player = dynamic_cast<PlayerObject*>(mObject);

    // make sure its a fully grouped player
    if(player->getGroupId() == 0)
    {
        return;
    }

    // we advise the chat server about it
    Message* newMessage;
    gMessageFactory->StartMessage();
    gMessageFactory->addUint32(opIsmGroupLootModeRequest);
    newMessage = gMessageFactory->EndMessage();
    player->getClient()->SendChannelA(newMessage,player->getAccountId(),CR_Chat,2);
}
Пример #15
0
void TravelMapHandler::_processTravelPointListRequest(Message* message,DispatchClient* client)
{
    PlayerObject* playerObject = dynamic_cast<PlayerObject*>(gWorldManager->getObjectById(message->getUint64()));

    if(playerObject != NULL && playerObject->isConnected())
    {
        // we need to know where we query from
        TravelTerminal* terminal = playerObject->getTravelPoint();

        if(terminal == NULL)
        {
            DLOG(INFO) << "TravelMapHandler::_processTravelListRequest: No TravelPosition set, player "<<playerObject->getId();
            return;
        }

        BString requestedPlanet;
        message->getStringAnsi(requestedPlanet);

        // find our planetId
        uint8 planetId = gWorldManager->getPlanetIdByName(requestedPlanet);

        char	queryPoint[64];
        TravelPoint* qP = NULL;

        // get our query point
        strcpy(queryPoint,(playerObject->getTravelPoint())->getPosDescriptor().getAnsi());

        TravelPointList::iterator it = mTravelPoints[mZoneId].begin();
        TravelPointList::iterator end = mTravelPoints[mZoneId].end();
        while(it != end)
        {
            TravelPoint* tp = (*it);

            if(strcmp(queryPoint,tp->descriptor) == 0)
            {
                qP = tp;
                break;
            }
            ++it;
        }

        TravelPointList printListing;
        it = mTravelPoints[planetId].begin();
        end = mTravelPoints[planetId].end();

        while(it != end)
        {
            // If the requested planet list is not the planet of the current zone
            // then only list it if the origin is a starport and the destination is a starport.
            if((mZoneId != planetId && qP->portType == 1 && (*it)->portType == 1) ||
                    mZoneId == planetId) // Show all starports/shuttleports on this planet.
            {
                printListing.push_back((*it));
            }
            ++it;
        }

        //Build our message.
        gMessageFactory->StartMessage();
        gMessageFactory->addUint32(opPlanetTravelPointListResponse);
        gMessageFactory->addString(requestedPlanet);

        end = printListing.end();
        gMessageFactory->addUint32(printListing.size());
        for(it = printListing.begin(); it != end; ++it)
        {
            gMessageFactory->addString((*it)->descriptor);
        }

        gMessageFactory->addUint32(printListing.size());
        for(it = printListing.begin(); it != end; ++it)
        {
            gMessageFactory->addFloat((*it)->x);
            gMessageFactory->addFloat((*it)->y);
            gMessageFactory->addFloat((*it)->z);
        }

        gMessageFactory->addUint32(printListing.size());
        for(it = printListing.begin(); it != end; ++it)
        {
            gMessageFactory->addUint32((*it)->taxes);
        }

        gMessageFactory->addUint32(printListing.size());
        for(it = printListing.begin(); it != end; ++it)
        {
            // If it's a starport send a 1, otherwise shuttleports are set to 0
            if ((*it)->portType == portType_Starport) {
                gMessageFactory->addUint8(1);
            } else {
                gMessageFactory->addUint8(0);
            }
        }

        playerObject->getClient()->SendChannelA(gMessageFactory->EndMessage(), playerObject->getAccountId(), CR_Client, 5);
    }
    else
        DLOG(INFO) << "TravelMapHandler::_processTravelListRequest: Couldnt find player for " << client->getAccountId();
}
bool WorldManager::addObject(Object* object,bool manual)
{
	uint64 key = object->getId();

	//make sure objects arnt added several times!!!!
	if(getObjectById(key))
	{
		gLogger->logMsgF("WorldManager::addObject Object already existant added several times or ID messup ???",MSG_HIGH);
		return false;
	}

	mObjectMap.insert(key,object);

	// if we want to set the parent manually or the object is from the snapshots and not a building, return
	if(manual)
	{
		return true;
	}

#if defined(_MSC_VER)
	if(object->getId() < 0x0000000100000000 && object->getType() != ObjType_Building)
#else
	if(object->getId() < 0x0000000100000000LLU && object->getType() != ObjType_Building)
#endif
	{
		// check if a crafting station - in that case add
		Item* item = dynamic_cast<Item*> (object);

		if(item)
		{
			if(!(item->getItemFamily() == ItemFamily_CraftingStations))
				return true;
		}
		else
		{
			return true;
		}
	}

	switch(object->getType())
	{
		// player, when a player enters a planet
		case ObjType_Player:
		{

			PlayerObject* player = dynamic_cast<PlayerObject*>(object);
			gLogger->logMsgF("New Player: %"PRIu64", Total Players on zone : %i",MSG_NORMAL,player->getId(),(getPlayerAccMap())->size() + 1);
			// insert into the player map
			mPlayerAccMap.insert(std::make_pair(player->getAccountId(),player));

			// insert into cell
			if(player->getParentId())
			{
				player->setSubZoneId(0);

				if(CellObject* cell = dynamic_cast<CellObject*>(getObjectById(player->getParentId())))
				{
					cell->addObjectSecure(player);
				}
				else
				{
					gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,player->getParentId());
				}
			}
			// query the rtree for the qt region we are in
			else
			{
				if(QTRegion* region = mSpatialIndex->getQTRegion(player->mPosition.x,player->mPosition.z))
				{
					player->setSubZoneId((uint32)region->getId());
					region->mTree->addObject(player);
				}
				else
				{
					// we should never get here !
					gLogger->logMsg("WorldManager::addObject: could not find zone region in map");
					return false;
				}
			}

			// initialize
			initObjectsInRange(player);
			gMessageLib->sendCreatePlayer(player,player);

			// add ham to regeneration scheduler
			player->getHam()->updateRegenRates();	// ERU: Note sure if this is needed here.
			player->getHam()->checkForRegen();

			// onPlayerEntered event, notify scripts
			string params;
			params.setLength(sprintf(params.getAnsi(),"%s %s %u",getPlanetNameThis(),player->getFirstName().getAnsi(),static_cast<uint32>(mPlayerAccMap.size())));

			mWorldScriptsListener.handleScriptEvent("onPlayerEntered",params);

			// Start player world position update. Used when player don't get any events from client (player not moving).
			// addPlayerMovementUpdateTime(player, 1000);
		}
		break;

		case ObjType_Structure:
		{
		//	HarvesterObject* harvester = dynamic_cast<HarvesterObject*>(object);
			mStructureList.push_back(object->getId());
			mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z);

		}
		break;

		case ObjType_Building:
		{
			mStructureList.push_back(object->getId());
			BuildingObject* building = dynamic_cast<BuildingObject*>(object);
			
			mSpatialIndex->InsertRegion(key,building->mPosition.x,building->mPosition.z,building->getWidth(),building->getHeight());
		}
		break;


		case ObjType_Tangible:
		{
			uint64 parentId = object->getParentId();

			if(parentId == 0)
			{
				mSpatialIndex->InsertPoint(key,object->mPosition.x,object->mPosition.z);
			}
			else
			{
				CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId));

				if(cell)
					cell->addObjectSecure(object);
				else
					gLogger->logMsgF("WorldManager::addObject couldn't find cell %"PRIu64"",MSG_NORMAL,parentId);
			}
		}
		break;

		// TODO: add moving creatures to qtregions
		case ObjType_NPC:
		case ObjType_Creature:
		case ObjType_Lair:
		{
			CreatureObject* creature = dynamic_cast<CreatureObject*>(object);

			if(creature->getCreoGroup() == CreoGroup_Shuttle)
				mShuttleList.push_back(dynamic_cast<Shuttle*>(creature));

			uint64 parentId = creature->getParentId();

			if(parentId)
			{
				CellObject* cell = dynamic_cast<CellObject*>(getObjectById(parentId));

				if(cell)
					cell->addObjectSecure(creature);
				else
					gLogger->logMsgF("WorldManager::addObject: couldn't find cell %"PRIu64"",MSG_HIGH,parentId);
			}
			else
			{

				switch(creature->getCreoGroup())
				{
					// moving creature, add to QT
					case CreoGroup_Vehicle :
					{
						if(QTRegion* region = mSpatialIndex->getQTRegion(creature->mPosition.x,creature->mPosition.z))
						{
							creature->setSubZoneId((uint32)region->getId());
							region->mTree->addObject(creature);
						}
						else
						{
							gLogger->logMsg("WorldManager::addObject: could not find zone region in map for creature");
							return false;
						}

					}
					break;

					// still creature, add to SI
					default :
					{
						mSpatialIndex->InsertPoint(key,creature->mPosition.x,creature->mPosition.z);
					}
				}


			}
		}
		break;

		case ObjType_Region:
		{
			RegionObject* region = dynamic_cast<RegionObject*>(object);

			mRegionMap.insert(std::make_pair(key,region));

			mSpatialIndex->InsertRegion(key,region->mPosition.x,region->mPosition.z,region->getWidth(),region->getHeight());

			if(region->getActive())
				addActiveRegion(region);
		}
		break;

		case ObjType_Intangible:
		{
			gLogger->logMsgF("Object of type ObjType_Intangible UNHANDLED in WorldManager::addObject:",MSG_HIGH);
		}
		break;

		default:
		{
			gLogger->logMsgF("Unhandled ObjectType in WorldManager::addObject: PRId32",MSG_HIGH,object->getType());
			// Please, when adding new stufff, at least take the time to add a stub for that type.
			// Better fail always, than have random crashes.
			assert(false && "WorldManager::addObject Unhandled ObjectType");
		}
		break;
	}
	return true;
}
Пример #17
0
void ObjectController::_handleGetAttributesBatch(uint64 targetId,Message* message,ObjectControllerCmdProperties* cmdProperties)
{
    PlayerObject*	playerObject	= dynamic_cast<PlayerObject*>(mObject);
    BString			requestStr;
    BStringVector	dataElements;
    BStringVector	dataElements2;
    uint16			elementCount;


    message->getStringUnicode16(requestStr);
    requestStr.convert(BSTRType_ANSI);
    requestStr.getRawData()[requestStr.getLength()] = 0;

    elementCount = requestStr.split(dataElements,' ');

    if(!elementCount)
    {
        return;
    }

    Message* newMessage;

    for(uint16 i = 0; i < elementCount; i++)
    {

        uint64 itemId	= boost::lexical_cast<uint64>(dataElements[i].getAnsi());
        Object* object	= gWorldManager->getObjectById(itemId);

        if(object == NULL)
        {
            // could be a resource
            Resource* resource = gResourceManager->getResourceById(itemId);

            if(resource != NULL)
            {
                resource->sendAttributes(playerObject);
                continue;
            }

            //could be a schematic!
            Datapad* datapad			= playerObject->getDataPad();
            ManufacturingSchematic* schem	= datapad->getManufacturingSchematicById(itemId);

            if(schem != NULL)
            {
                schem->sendAttributes(playerObject);
                continue;
            }

            MissionObject* mission			= datapad->getMissionById(itemId);
            if(mission != NULL)
            {
                mission->sendAttributes(playerObject);
                continue;
            }

            IntangibleObject* data = datapad->getDataById(itemId);
            if(data != NULL)
            {
                data->sendAttributes(playerObject);
                continue;
            }

            // TODO: check our datapad items
            if(playerObject->isConnected())
            {
                // default reply for schematics
                gMessageFactory->StartMessage();
                gMessageFactory->addUint32(opAttributeListMessage);
                gMessageFactory->addUint64(itemId);
                gMessageFactory->addUint32(0);
                //gMessageFactory->addUint16(0);
                //gMessageFactory->addUint32(40);

                newMessage = gMessageFactory->EndMessage();

                (playerObject->getClient())->SendChannelAUnreliable(newMessage, playerObject->getAccountId(),  CR_Client, 8);
            }

            //finally, when we are crafting this could be the new item, not yet added to the worldmanager??
            if(playerObject->getCraftingSession())
            {
                if(playerObject->getCraftingSession()->getItem()&&playerObject->getCraftingSession()->getItem()->getId() == itemId)
                {
                    playerObject->getCraftingSession()->getItem()->sendAttributes(playerObject);
                }
            }
        }
        else
        {
            // Tutorial: I (Eru) have to do some hacks here, since I don't know how to get the info of what object the client has selected (by single click) in the Inventory.
            if (gWorldConfig->isTutorial())
            {
                // Let's see if the actual object is the food item "Melon" in our inventory.
                if (dynamic_cast<Inventory*>(playerObject->getEquipManager()->getEquippedObject(CreatureEquipSlot_Inventory))->getId() == object->getParentId())
                {
                    //uint64 id = object->getId();

                    // Is it an Item?
                    Item* item = dynamic_cast<Item*>(object);

                    // Check if this item is a food item.
                    if (item)
                    {
                        if (item->getItemFamily() == ItemFamily_Foods)
                        {
                            playerObject->getTutorial()->tutorialResponse("foodSelected");
                        }
                    }
                }
            }

            object->sendAttributes(playerObject);
        }
    }
}