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() << "]"; } }
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); }
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); }
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); } } }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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; }
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); } } }