Revert "fix: update player container on shutdown (#1704)"

This reverts commit 3ecbd1013b90678e178c0e4a4d2b53e1513f1419.
This commit is contained in:
David Markowitz 2025-01-07 18:45:51 -08:00
parent b173d7069e
commit 4b31a9dc1a
4 changed files with 158 additions and 201 deletions

View File

@ -29,35 +29,33 @@ void ChatPacketHandler::HandleFriendlistRequest(Packet* packet) {
auto& player = Game::playerContainer.GetPlayerDataMutable(playerID); auto& player = Game::playerContainer.GetPlayerDataMutable(playerID);
if (!player) return; if (!player) return;
if (player.friends.empty()) { auto friendsList = Database::Get()->GetFriendsList(playerID);
auto friendsList = Database::Get()->GetFriendsList(playerID); for (const auto& friendData : friendsList) {
for (const auto& friendData : friendsList) { FriendData fd;
FriendData fd; fd.isFTP = false; // not a thing in DLU
fd.isFTP = false; // not a thing in DLU fd.friendID = friendData.friendID;
fd.friendID = friendData.friendID; GeneralUtils::SetBit(fd.friendID, eObjectBits::PERSISTENT);
GeneralUtils::SetBit(fd.friendID, eObjectBits::PERSISTENT); GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
GeneralUtils::SetBit(fd.friendID, eObjectBits::CHARACTER);
fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs fd.isBestFriend = friendData.isBestFriend; //0 = friends, 1 = left_requested, 2 = right_requested, 3 = both_accepted - are now bffs
if (fd.isBestFriend) player.countOfBestFriends += 1; if (fd.isBestFriend) player.countOfBestFriends += 1;
fd.friendName = friendData.friendName; fd.friendName = friendData.friendName;
//Now check if they're online: //Now check if they're online:
const auto& fr = Game::playerContainer.GetPlayerData(fd.friendID); const auto& fr = Game::playerContainer.GetPlayerData(fd.friendID);
if (fr) { if (fr) {
fd.isOnline = true; fd.isOnline = true;
fd.zoneID = fr.zoneID; fd.zoneID = fr.zoneID;
//Since this friend is online, we need to update them on the fact that we've just logged in: //Since this friend is online, we need to update them on the fact that we've just logged in:
SendFriendUpdate(fr, player, 1, fd.isBestFriend); SendFriendUpdate(fr, player, 1, fd.isBestFriend);
} else { } else {
fd.isOnline = false; fd.isOnline = false;
fd.zoneID = LWOZONEID(); fd.zoneID = LWOZONEID();
}
player.friends.push_back(fd);
} }
player.friends.push_back(fd);
} }
//Now, we need to send the friendlist to the server they came from: //Now, we need to send the friendlist to the server they came from:
@ -142,7 +140,7 @@ void ChatPacketHandler::HandleFriendRequest(Packet* packet) {
// Prevent GM friend spam // Prevent GM friend spam
// If the player we are trying to be friends with is not a civilian and we are a civilian, abort the process // If the player we are trying to be friends with is not a civilian and we are a civilian, abort the process
if (requestee.gmLevel > eGameMasterLevel::CIVILIAN && requestor.gmLevel == eGameMasterLevel::CIVILIAN) { if (requestee.gmLevel > eGameMasterLevel::CIVILIAN && requestor.gmLevel == eGameMasterLevel::CIVILIAN ) {
SendFriendResponse(requestor, requestee, eAddFriendResponseType::MYTHRAN); SendFriendResponse(requestor, requestee, eAddFriendResponseType::MYTHRAN);
return; return;
} }
@ -402,8 +400,8 @@ void ChatPacketHandler::HandleShowAll(Packet* packet) {
bitStream.Write(Game::playerContainer.GetSimCount()); bitStream.Write(Game::playerContainer.GetSimCount());
bitStream.Write<uint8_t>(request.displayIndividualPlayers); bitStream.Write<uint8_t>(request.displayIndividualPlayers);
bitStream.Write<uint8_t>(request.displayZoneData); bitStream.Write<uint8_t>(request.displayZoneData);
if (request.displayZoneData || request.displayIndividualPlayers) { if (request.displayZoneData || request.displayIndividualPlayers){
for (auto& [playerID, playerData] : Game::playerContainer.GetAllPlayers()) { for (auto& [playerID, playerData ]: Game::playerContainer.GetAllPlayers()){
if (!playerData) continue; if (!playerData) continue;
bitStream.Write<uint8_t>(0); // structure packing bitStream.Write<uint8_t>(0); // structure packing
if (request.displayIndividualPlayers) bitStream.Write(LUWString(playerData.playerName)); if (request.displayIndividualPlayers) bitStream.Write(LUWString(playerData.playerName));

View File

@ -122,8 +122,6 @@ int main(int argc, char** argv) {
uint32_t framesSinceMasterDisconnect = 0; uint32_t framesSinceMasterDisconnect = 0;
uint32_t framesSinceLastSQLPing = 0; uint32_t framesSinceLastSQLPing = 0;
auto lastTime = std::chrono::high_resolution_clock::now();
Game::logger->Flush(); // once immediately before main loop Game::logger->Flush(); // once immediately before main loop
while (!Game::ShouldShutdown()) { while (!Game::ShouldShutdown()) {
//Check if we're still connected to master: //Check if we're still connected to master:
@ -134,11 +132,7 @@ int main(int argc, char** argv) {
break; //Exit our loop, shut down. break; //Exit our loop, shut down.
} else framesSinceMasterDisconnect = 0; } else framesSinceMasterDisconnect = 0;
const auto currentTime = std::chrono::high_resolution_clock::now(); //In world we'd update our other systems here.
const float deltaTime = std::chrono::duration<float>(currentTime - lastTime).count();
lastTime = currentTime;
Game::playerContainer.Update(deltaTime);
//Check for packets here: //Check for packets here:
Game::server->ReceiveFromMaster(); //ReceiveFromMaster also handles the master packets if needed. Game::server->ReceiveFromMaster(); //ReceiveFromMaster also handles the master packets if needed.
@ -174,7 +168,7 @@ int main(int argc, char** argv) {
t += std::chrono::milliseconds(chatFrameDelta); //Chat can run at a lower "fps" t += std::chrono::milliseconds(chatFrameDelta); //Chat can run at a lower "fps"
std::this_thread::sleep_until(t); std::this_thread::sleep_until(t);
} }
Game::playerContainer.Shutdown();
//Delete our objects here: //Delete our objects here:
Database::Destroy("ChatServer"); Database::Destroy("ChatServer");
delete Game::server; delete Game::server;
@ -203,150 +197,150 @@ void HandlePacket(Packet* packet) {
inStream.Read(chatMessageID); inStream.Read(chatMessageID);
switch (chatMessageID) { switch (chatMessageID) {
case MessageType::Chat::GM_MUTE: case MessageType::Chat::GM_MUTE:
Game::playerContainer.MuteUpdate(packet); Game::playerContainer.MuteUpdate(packet);
break; break;
case MessageType::Chat::CREATE_TEAM: case MessageType::Chat::CREATE_TEAM:
Game::playerContainer.CreateTeamServer(packet); Game::playerContainer.CreateTeamServer(packet);
break; break;
case MessageType::Chat::GET_FRIENDS_LIST: case MessageType::Chat::GET_FRIENDS_LIST:
ChatPacketHandler::HandleFriendlistRequest(packet); ChatPacketHandler::HandleFriendlistRequest(packet);
break; break;
case MessageType::Chat::GET_IGNORE_LIST: case MessageType::Chat::GET_IGNORE_LIST:
ChatIgnoreList::GetIgnoreList(packet); ChatIgnoreList::GetIgnoreList(packet);
break; break;
case MessageType::Chat::ADD_IGNORE: case MessageType::Chat::ADD_IGNORE:
ChatIgnoreList::AddIgnore(packet); ChatIgnoreList::AddIgnore(packet);
break; break;
case MessageType::Chat::REMOVE_IGNORE: case MessageType::Chat::REMOVE_IGNORE:
ChatIgnoreList::RemoveIgnore(packet); ChatIgnoreList::RemoveIgnore(packet);
break; break;
case MessageType::Chat::TEAM_GET_STATUS: case MessageType::Chat::TEAM_GET_STATUS:
ChatPacketHandler::HandleTeamStatusRequest(packet); ChatPacketHandler::HandleTeamStatusRequest(packet);
break; break;
case MessageType::Chat::ADD_FRIEND_REQUEST: case MessageType::Chat::ADD_FRIEND_REQUEST:
//this involves someone sending the initial request, the response is below, response as in from the other player. //this involves someone sending the initial request, the response is below, response as in from the other player.
//We basically just check to see if this player is online or not and route the packet. //We basically just check to see if this player is online or not and route the packet.
ChatPacketHandler::HandleFriendRequest(packet); ChatPacketHandler::HandleFriendRequest(packet);
break; break;
case MessageType::Chat::ADD_FRIEND_RESPONSE: case MessageType::Chat::ADD_FRIEND_RESPONSE:
//This isn't the response a server sent, rather it is a player's response to a received request. //This isn't the response a server sent, rather it is a player's response to a received request.
//Here, we'll actually have to add them to eachother's friend lists depending on the response code. //Here, we'll actually have to add them to eachother's friend lists depending on the response code.
ChatPacketHandler::HandleFriendResponse(packet); ChatPacketHandler::HandleFriendResponse(packet);
break; break;
case MessageType::Chat::REMOVE_FRIEND: case MessageType::Chat::REMOVE_FRIEND:
ChatPacketHandler::HandleRemoveFriend(packet); ChatPacketHandler::HandleRemoveFriend(packet);
break; break;
case MessageType::Chat::GENERAL_CHAT_MESSAGE: case MessageType::Chat::GENERAL_CHAT_MESSAGE:
ChatPacketHandler::HandleChatMessage(packet); ChatPacketHandler::HandleChatMessage(packet);
break; break;
case MessageType::Chat::PRIVATE_CHAT_MESSAGE: case MessageType::Chat::PRIVATE_CHAT_MESSAGE:
//This message is supposed to be echo'd to both the sender and the receiver //This message is supposed to be echo'd to both the sender and the receiver
//BUT: they have to have different responseCodes, so we'll do some of the ol hacky wacky to fix that right up. //BUT: they have to have different responseCodes, so we'll do some of the ol hacky wacky to fix that right up.
ChatPacketHandler::HandlePrivateChatMessage(packet); ChatPacketHandler::HandlePrivateChatMessage(packet);
break; break;
case MessageType::Chat::TEAM_INVITE: case MessageType::Chat::TEAM_INVITE:
ChatPacketHandler::HandleTeamInvite(packet); ChatPacketHandler::HandleTeamInvite(packet);
break; break;
case MessageType::Chat::TEAM_INVITE_RESPONSE: case MessageType::Chat::TEAM_INVITE_RESPONSE:
ChatPacketHandler::HandleTeamInviteResponse(packet); ChatPacketHandler::HandleTeamInviteResponse(packet);
break; break;
case MessageType::Chat::TEAM_LEAVE: case MessageType::Chat::TEAM_LEAVE:
ChatPacketHandler::HandleTeamLeave(packet); ChatPacketHandler::HandleTeamLeave(packet);
break; break;
case MessageType::Chat::TEAM_SET_LEADER: case MessageType::Chat::TEAM_SET_LEADER:
ChatPacketHandler::HandleTeamPromote(packet); ChatPacketHandler::HandleTeamPromote(packet);
break; break;
case MessageType::Chat::TEAM_KICK: case MessageType::Chat::TEAM_KICK:
ChatPacketHandler::HandleTeamKick(packet); ChatPacketHandler::HandleTeamKick(packet);
break; break;
case MessageType::Chat::TEAM_SET_LOOT: case MessageType::Chat::TEAM_SET_LOOT:
ChatPacketHandler::HandleTeamLootOption(packet); ChatPacketHandler::HandleTeamLootOption(packet);
break; break;
case MessageType::Chat::GMLEVEL_UPDATE: case MessageType::Chat::GMLEVEL_UPDATE:
ChatPacketHandler::HandleGMLevelUpdate(packet); ChatPacketHandler::HandleGMLevelUpdate(packet);
break; break;
case MessageType::Chat::LOGIN_SESSION_NOTIFY: case MessageType::Chat::LOGIN_SESSION_NOTIFY:
Game::playerContainer.InsertPlayer(packet); Game::playerContainer.InsertPlayer(packet);
break; break;
case MessageType::Chat::GM_ANNOUNCE: { case MessageType::Chat::GM_ANNOUNCE:{
// we just forward this packet to every connected server // we just forward this packet to every connected server
inStream.ResetReadPointer(); inStream.ResetReadPointer();
Game::server->Send(inStream, packet->systemAddress, true); // send to everyone except origin Game::server->Send(inStream, packet->systemAddress, true); // send to everyone except origin
} }
break; break;
case MessageType::Chat::UNEXPECTED_DISCONNECT: case MessageType::Chat::UNEXPECTED_DISCONNECT:
Game::playerContainer.ScheduleRemovePlayer(packet); Game::playerContainer.RemovePlayer(packet);
break; break;
case MessageType::Chat::WHO: case MessageType::Chat::WHO:
ChatPacketHandler::HandleWho(packet); ChatPacketHandler::HandleWho(packet);
break; break;
case MessageType::Chat::SHOW_ALL: case MessageType::Chat::SHOW_ALL:
ChatPacketHandler::HandleShowAll(packet); ChatPacketHandler::HandleShowAll(packet);
break; break;
case MessageType::Chat::USER_CHANNEL_CHAT_MESSAGE: case MessageType::Chat::USER_CHANNEL_CHAT_MESSAGE:
case MessageType::Chat::WORLD_DISCONNECT_REQUEST: case MessageType::Chat::WORLD_DISCONNECT_REQUEST:
case MessageType::Chat::WORLD_PROXIMITY_RESPONSE: case MessageType::Chat::WORLD_PROXIMITY_RESPONSE:
case MessageType::Chat::WORLD_PARCEL_RESPONSE: case MessageType::Chat::WORLD_PARCEL_RESPONSE:
case MessageType::Chat::TEAM_MISSED_INVITE_CHECK: case MessageType::Chat::TEAM_MISSED_INVITE_CHECK:
case MessageType::Chat::GUILD_CREATE: case MessageType::Chat::GUILD_CREATE:
case MessageType::Chat::GUILD_INVITE: case MessageType::Chat::GUILD_INVITE:
case MessageType::Chat::GUILD_INVITE_RESPONSE: case MessageType::Chat::GUILD_INVITE_RESPONSE:
case MessageType::Chat::GUILD_LEAVE: case MessageType::Chat::GUILD_LEAVE:
case MessageType::Chat::GUILD_KICK: case MessageType::Chat::GUILD_KICK:
case MessageType::Chat::GUILD_GET_STATUS: case MessageType::Chat::GUILD_GET_STATUS:
case MessageType::Chat::GUILD_GET_ALL: case MessageType::Chat::GUILD_GET_ALL:
case MessageType::Chat::BLUEPRINT_MODERATED: case MessageType::Chat::BLUEPRINT_MODERATED:
case MessageType::Chat::BLUEPRINT_MODEL_READY: case MessageType::Chat::BLUEPRINT_MODEL_READY:
case MessageType::Chat::PROPERTY_READY_FOR_APPROVAL: case MessageType::Chat::PROPERTY_READY_FOR_APPROVAL:
case MessageType::Chat::PROPERTY_MODERATION_CHANGED: case MessageType::Chat::PROPERTY_MODERATION_CHANGED:
case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED: case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED:
case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED_REPORT: case MessageType::Chat::PROPERTY_BUILDMODE_CHANGED_REPORT:
case MessageType::Chat::MAIL: case MessageType::Chat::MAIL:
case MessageType::Chat::WORLD_INSTANCE_LOCATION_REQUEST: case MessageType::Chat::WORLD_INSTANCE_LOCATION_REQUEST:
case MessageType::Chat::REPUTATION_UPDATE: case MessageType::Chat::REPUTATION_UPDATE:
case MessageType::Chat::SEND_CANNED_TEXT: case MessageType::Chat::SEND_CANNED_TEXT:
case MessageType::Chat::CHARACTER_NAME_CHANGE_REQUEST: case MessageType::Chat::CHARACTER_NAME_CHANGE_REQUEST:
case MessageType::Chat::CSR_REQUEST: case MessageType::Chat::CSR_REQUEST:
case MessageType::Chat::CSR_REPLY: case MessageType::Chat::CSR_REPLY:
case MessageType::Chat::GM_KICK: case MessageType::Chat::GM_KICK:
case MessageType::Chat::WORLD_ROUTE_PACKET: case MessageType::Chat::WORLD_ROUTE_PACKET:
case MessageType::Chat::GET_ZONE_POPULATIONS: case MessageType::Chat::GET_ZONE_POPULATIONS:
case MessageType::Chat::REQUEST_MINIMUM_CHAT_MODE: case MessageType::Chat::REQUEST_MINIMUM_CHAT_MODE:
case MessageType::Chat::MATCH_REQUEST: case MessageType::Chat::MATCH_REQUEST:
case MessageType::Chat::UGCMANIFEST_REPORT_MISSING_FILE: case MessageType::Chat::UGCMANIFEST_REPORT_MISSING_FILE:
case MessageType::Chat::UGCMANIFEST_REPORT_DONE_FILE: case MessageType::Chat::UGCMANIFEST_REPORT_DONE_FILE:
case MessageType::Chat::UGCMANIFEST_REPORT_DONE_BLUEPRINT: case MessageType::Chat::UGCMANIFEST_REPORT_DONE_BLUEPRINT:
case MessageType::Chat::UGCC_REQUEST: case MessageType::Chat::UGCC_REQUEST:
case MessageType::Chat::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE: case MessageType::Chat::WORLD_PLAYERS_PET_MODERATED_ACKNOWLEDGE:
case MessageType::Chat::ACHIEVEMENT_NOTIFY: case MessageType::Chat::ACHIEVEMENT_NOTIFY:
case MessageType::Chat::GM_CLOSE_PRIVATE_CHAT_WINDOW: case MessageType::Chat::GM_CLOSE_PRIVATE_CHAT_WINDOW:
case MessageType::Chat::PLAYER_READY: case MessageType::Chat::PLAYER_READY:
case MessageType::Chat::GET_DONATION_TOTAL: case MessageType::Chat::GET_DONATION_TOTAL:
case MessageType::Chat::UPDATE_DONATION: case MessageType::Chat::UPDATE_DONATION:
case MessageType::Chat::PRG_CSR_COMMAND: case MessageType::Chat::PRG_CSR_COMMAND:
case MessageType::Chat::HEARTBEAT_REQUEST_FROM_WORLD: case MessageType::Chat::HEARTBEAT_REQUEST_FROM_WORLD:
case MessageType::Chat::UPDATE_FREE_TRIAL_STATUS: case MessageType::Chat::UPDATE_FREE_TRIAL_STATUS:
LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chatMessageID).data(), chatMessageID); LOG("Unhandled CHAT Message id: %s (%i)", StringifiedEnum::ToString(chatMessageID).data(), chatMessageID);
break; break;
default: default:
LOG("Unknown CHAT Message id: %i", chatMessageID); LOG("Unknown CHAT Message id: %i", chatMessageID);
} }
} }

View File

@ -57,32 +57,13 @@ void PlayerContainer::InsertPlayer(Packet* packet) {
LOG("Added user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID()); LOG("Added user: %s (%llu), zone: %i", data.playerName.c_str(), data.playerID, data.zoneID.GetMapID());
Database::Get()->UpdateActivityLog(data.playerID, eActivityType::PlayerLoggedIn, data.zoneID.GetMapID()); Database::Get()->UpdateActivityLog(data.playerID, eActivityType::PlayerLoggedIn, data.zoneID.GetMapID());
m_PlayersToRemove.erase(playerId);
} }
void PlayerContainer::ScheduleRemovePlayer(Packet* packet) { void PlayerContainer::RemovePlayer(Packet* packet) {
CINSTREAM_SKIP_HEADER; CINSTREAM_SKIP_HEADER;
LWOOBJID playerID{ LWOOBJID_EMPTY }; LWOOBJID playerID;
inStream.Read(playerID); inStream.Read(playerID);
constexpr float updatePlayerOnLogoutTime = 20.0f;
if (playerID != LWOOBJID_EMPTY) m_PlayersToRemove.insert_or_assign(playerID, updatePlayerOnLogoutTime);
}
void PlayerContainer::Update(const float deltaTime) {
for (auto it = m_PlayersToRemove.begin(); it != m_PlayersToRemove.end();) {
auto& [id, time] = *it;
time -= deltaTime;
if (time <= 0.0f) {
RemovePlayer(id);
it = m_PlayersToRemove.erase(it);
} else {
++it;
}
}
}
void PlayerContainer::RemovePlayer(const LWOOBJID playerID) {
//Before they get kicked, we need to also send a message to their friends saying that they disconnected. //Before they get kicked, we need to also send a message to their friends saying that they disconnected.
const auto& player = GetPlayerData(playerID); const auto& player = GetPlayerData(playerID);
@ -436,13 +417,3 @@ const PlayerData& PlayerContainer::GetPlayerData(const LWOOBJID& playerID) {
const PlayerData& PlayerContainer::GetPlayerData(const std::string& playerName) { const PlayerData& PlayerContainer::GetPlayerData(const std::string& playerName) {
return GetPlayerDataMutable(playerName); return GetPlayerDataMutable(playerName);
} }
void PlayerContainer::Shutdown() {
m_Players.erase(LWOOBJID_EMPTY);
while (!m_Players.empty()) {
const auto& [id, playerData] = *m_Players.begin();
Database::Get()->UpdateActivityLog(id, eActivityType::PlayerLoggedOut, playerData.zoneID.GetMapID());
m_Players.erase(m_Players.begin());
}
for (auto* team : mTeams) if (team) delete team;
}

View File

@ -62,12 +62,10 @@ class PlayerContainer {
public: public:
void Initialize(); void Initialize();
void InsertPlayer(Packet* packet); void InsertPlayer(Packet* packet);
void ScheduleRemovePlayer(Packet* packet); void RemovePlayer(Packet* packet);
void RemovePlayer(const LWOOBJID playerID);
void MuteUpdate(Packet* packet); void MuteUpdate(Packet* packet);
void CreateTeamServer(Packet* packet); void CreateTeamServer(Packet* packet);
void BroadcastMuteUpdate(LWOOBJID player, time_t time); void BroadcastMuteUpdate(LWOOBJID player, time_t time);
void Shutdown();
const PlayerData& GetPlayerData(const LWOOBJID& playerID); const PlayerData& GetPlayerData(const LWOOBJID& playerID);
const PlayerData& GetPlayerData(const std::string& playerName); const PlayerData& GetPlayerData(const std::string& playerName);
@ -91,15 +89,11 @@ public:
uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; } uint32_t GetMaxNumberOfBestFriends() { return m_MaxNumberOfBestFriends; }
uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; } uint32_t GetMaxNumberOfFriends() { return m_MaxNumberOfFriends; }
void Update(const float deltaTime);
bool PlayerBeingRemoved(const LWOOBJID playerID) { return m_PlayersToRemove.contains(playerID); }
private: private:
LWOOBJID m_TeamIDCounter = 0; LWOOBJID m_TeamIDCounter = 0;
std::map<LWOOBJID, PlayerData> m_Players; std::map<LWOOBJID, PlayerData> m_Players;
std::vector<TeamData*> mTeams; std::vector<TeamData*> mTeams;
std::unordered_map<LWOOBJID, std::u16string> m_Names; std::unordered_map<LWOOBJID, std::u16string> m_Names;
std::map<LWOOBJID, float> m_PlayersToRemove;
uint32_t m_MaxNumberOfBestFriends = 5; uint32_t m_MaxNumberOfBestFriends = 5;
uint32_t m_MaxNumberOfFriends = 50; uint32_t m_MaxNumberOfFriends = 50;
uint32_t m_PlayerCount = 0; uint32_t m_PlayerCount = 0;