DarkflameServer/dGame/dComponents/PropertyEntranceComponent.cpp

179 lines
6.7 KiB
C++
Raw Normal View History

#include "PropertyEntranceComponent.h"
2022-03-31 03:33:50 +00:00
#include "CDPropertyEntranceComponentTable.h"
2022-03-31 03:33:50 +00:00
#include "Character.h"
#include "Database.h"
2022-03-31 03:33:50 +00:00
#include "GameMessages.h"
#include "PropertyManagementComponent.h"
2022-03-31 03:33:50 +00:00
#include "PropertySelectQueryProperty.h"
#include "RocketLaunchpadControlComponent.h"
#include "CharacterComponent.h"
2022-03-28 03:04:45 +00:00
#include "UserManager.h"
#include "Logger.h"
#include "Amf3.h"
#include "eObjectBits.h"
#include "eGameMasterLevel.h"
#include "ePropertySortType.h"
#include "User.h"
feat: Add isolated and simplified path to add components (#1204) * Components: Make ComponentType inline Prevents the next commits ODR violation * Components: Add new components * Entity: Add headers inline script component ComponentType * Components: Flip constructor argument order Entity comes first always * Entity: Add generic AddComponent Allows for much easier adding of components and is error proof by not allowing the user to add more than 1 of a specific component type to an Entity. * Entity: Migrate all component constructors Move all to the new variadic templates AddComponent function to reduce clutter and ways the component map is modified. The new function makes no assumptions. Component is assumed to not exist and is checked for with operator[]. This will construct a null component which will then be newed if the component didnt exist, or it will just get the current component if it does already exist. No new component will be allocated or constructed if the component already exists and the already existing pointer is returned instead. * Entity: Add placement new For the case where the component may already exist, use a placement new to construct the component again, it would be constructed again, but would not need to go through the allocator. * Entity: Add comments on likely new code * Tests: Fix tests * Update Entity.cpp * Update SGCannon.cpp * Entity: call destructor when re-constructing * Update Entity.cpp Update Entity.cpp --------- Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com>
2023-10-23 01:08:49 +00:00
PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) {
2022-07-28 13:39:57 +00:00
this->propertyQueries = {};
auto table = CDClientManager::GetTable<CDPropertyEntranceComponentTable>();
2022-07-28 13:39:57 +00:00
const auto& entry = table->GetByID(componentID);
2022-07-28 13:39:57 +00:00
this->m_MapID = entry.mapID;
this->m_PropertyName = entry.propertyName;
}
void PropertyEntranceComponent::OnUse(Entity* entity) {
auto* characterComponent = entity->GetComponent<CharacterComponent>();
if (!characterComponent) return;
auto* rocket = entity->GetComponent<CharacterComponent>()->RocketEquip(entity);
if (!rocket) return;
GameMessages::SendPropertyEntranceBegin(m_Parent->GetObjectID(), entity->GetSystemAddress());
AMFArrayValue args;
args.Insert("state", "property_menu");
GameMessages::SendUIMessageServerToSingleClient(entity, entity->GetSystemAddress(), "pushGameState", args);
}
2022-07-28 13:39:57 +00:00
void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index, bool returnToZone, const SystemAddress& sysAddr) {
LWOCLONEID cloneId = 0;
2022-07-28 13:39:57 +00:00
if (index == -1 && !returnToZone) {
cloneId = entity->GetCharacter()->GetPropertyCloneID();
} else if (index == -1 && returnToZone) {
cloneId = 0;
} else if (index >= 0) {
// Increment index once here because the first index of other player properties is 2 in the propertyQueries cache.
index++;
2022-07-28 13:39:57 +00:00
const auto& pair = propertyQueries.find(entity->GetObjectID());
2022-07-28 13:39:57 +00:00
if (pair == propertyQueries.end()) return;
2022-07-28 13:39:57 +00:00
const auto& query = pair->second;
2022-07-28 13:39:57 +00:00
if (index >= query.size()) return;
2022-07-28 13:39:57 +00:00
cloneId = query[index].CloneId;
}
2022-07-28 13:39:57 +00:00
auto* launcher = m_Parent->GetComponent<RocketLaunchpadControlComponent>();
2022-07-28 13:39:57 +00:00
if (launcher == nullptr) {
return;
}
2022-07-28 13:39:57 +00:00
launcher->SetSelectedCloneId(entity->GetObjectID(), cloneId);
2022-07-28 13:39:57 +00:00
launcher->Launch(entity, launcher->GetTargetZone(), cloneId);
}
2022-07-28 13:39:57 +00:00
void PropertyEntranceComponent::OnPropertyEntranceSync(Entity* entity, bool includeNullAddress, bool includeNullDescription, bool playerOwn, bool updateUi, int32_t numResults, int32_t lReputationTime, int32_t sortMethod, int32_t startIndex, std::string filterText, const SystemAddress& sysAddr) {
const auto* const character = entity->GetCharacter();
2022-07-28 13:39:57 +00:00
if (!character) return;
const auto* const user = character->GetParentUser();
if (!user) return;
2022-03-29 03:51:15 +00:00
auto& entries = propertyQueries[entity->GetObjectID()];
entries.clear();
2022-07-28 13:39:57 +00:00
// Player property goes in index 1 of the vector. This is how the client expects it.
const auto playerProperty = Database::Get()->GetPropertyInfo(m_MapID, character->GetPropertyCloneID());
2022-07-28 13:39:57 +00:00
// If the player has a property this query will have a single result.
auto& playerEntry = entries.emplace_back();
if (playerProperty.has_value()) {
playerEntry.OwnerName = character->GetName();
playerEntry.IsBestFriend = true;
playerEntry.IsFriend = true;
playerEntry.IsAlt = true;
playerEntry.IsOwned = true;
playerEntry.CloneId = playerProperty->cloneId;
playerEntry.Name = playerProperty->name;
playerEntry.Description = playerProperty->description;
playerEntry.AccessType = playerProperty->privacyOption;
playerEntry.IsModeratorApproved = playerProperty->modApproved;
playerEntry.DateLastPublished = playerProperty->lastUpdatedTime;
playerEntry.Reputation = playerProperty->reputation;
playerEntry.PerformanceCost = playerProperty->performanceCost;
auto& entry = playerEntry;
2022-07-28 13:39:57 +00:00
} else {
playerEntry.OwnerName = character->GetName();
playerEntry.IsBestFriend = true;
playerEntry.IsFriend = true;
playerEntry.IsAlt = false;
playerEntry.IsOwned = false;
playerEntry.CloneId = character->GetPropertyCloneID();
playerEntry.Name = "";
playerEntry.Description = "";
playerEntry.AccessType = 0;
playerEntry.IsModeratorApproved = false;
playerEntry.DateLastPublished = 0;
playerEntry.Reputation = 0;
playerEntry.PerformanceCost = 0.0f;
2022-07-28 13:39:57 +00:00
}
IProperty::PropertyLookup propertyLookup;
propertyLookup.mapId = m_MapID;
propertyLookup.searchString = filterText;
propertyLookup.sortChoice = static_cast<ePropertySortType>(sortMethod);
propertyLookup.playerSort = static_cast<uint32_t>(sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? PropertyPrivacyOption::Friends : PropertyPrivacyOption::Public);
propertyLookup.playerId = character->GetID();
propertyLookup.numResults = numResults;
propertyLookup.startIndex = startIndex;
const auto lookupResult = Database::Get()->GetProperties(propertyLookup);
for (const auto& propertyEntry : lookupResult->entries) {
const auto owner = propertyEntry.ownerId;
const auto otherCharacter = Database::Get()->GetCharacterInfo(owner);
if (!otherCharacter.has_value()) {
LOG("Failed to find property owner name for %u!", owner);
2022-07-28 13:39:57 +00:00
continue;
}
auto& entry = entries.emplace_back();
entry.IsOwned = entry.CloneId == otherCharacter->cloneId;
entry.OwnerName = otherCharacter->name;
entry.CloneId = propertyEntry.cloneId;
entry.Name = propertyEntry.name;
entry.Description = propertyEntry.description;
entry.AccessType = propertyEntry.privacyOption;
entry.IsModeratorApproved = propertyEntry.modApproved;
entry.DateLastPublished = propertyEntry.lastUpdatedTime;
entry.Reputation = propertyEntry.reputation;
entry.PerformanceCost = propertyEntry.performanceCost;
entry.IsBestFriend = false;
entry.IsFriend = false;
2022-07-28 13:39:57 +00:00
// Query to get friend and best friend fields
const auto friendCheck = Database::Get()->GetBestFriendStatus(character->GetID(), owner);
2022-07-28 13:39:57 +00:00
// If we got a result than the two players are friends.
if (friendCheck.has_value()) {
entry.IsFriend = true;
entry.IsBestFriend = friendCheck->bestFriendStatus == 3;
2022-07-28 13:39:57 +00:00
}
2022-03-29 03:51:15 +00:00
if (!entry.IsModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
entry.Name = "[AWAITING APPROVAL]";
entry.Description = "[AWAITING APPROVAL]";
entry.IsModeratorApproved = true;
2022-07-28 13:39:57 +00:00
}
2022-03-28 06:46:43 +00:00
2022-07-28 13:39:57 +00:00
// Query to determine whether this property is an alt character of the entity.
for (const auto charid : Database::Get()->GetAccountCharacterIds(user->GetAccountID())) {
entry.IsAlt = charid == owner;
if (entry.IsAlt) break;
2022-07-28 13:39:57 +00:00
}
}
2022-07-28 13:39:57 +00:00
// Query here is to figure out whether or not to display the button to go to the next page or not.
GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, lookupResult->totalEntriesMatchingQuery - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr);
Add Aarch64 support (#231) * added mariadb-connector-cpp submodule * raknet aarch64 support * fix compile errors * mariadb connector swap (in progress) * update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors * update types with missing aarch64 check * corrected adding extra flag to properly compile mariadbconn in CMakeLists * updated readme with arm builds section * fix build failure if test folder does not exist * Remove mysql connector from all builds, add mariadbconnector to windows build * readd Linux check for backtrace lib to CMakeLists.txt * Separate system specific mariadbconncpp extra compile flags * Copy dlls to exes directory once built * fetch prebuilt binaries on windows so that ClangCL can be used * Delay load dll so that plugin directory is set correctly * Fixed typo in glibcxx compile flag * whitespacing, spaces -> tabs * Updated README.md, included instructions to update * Updated README.md added libssl-dev requirement and removed mysql connector references from macOS builds section * apple compile fixes for zlib and shared library name * add windows arm64 checks to raknet * remove extra . in shared library location * Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple * Fix copy paths for single config generators and non windows * change plugin folder location, another single config generator fix * GENERATOR_IS_MULTI_CONFIG is a property not a variable * Fixed a few errors after merge * Fix plugin directory path, force windows to look at the right folder * fixed directory name for make_directory command * Update README.md Updated MacOS, Windows build instructions. * set INSTALL_PLUGINDIR so that the right directory is used * Support for relative rpath for docker build * added mariadb-connector-cpp submodule * raknet aarch64 support * fix compile errors * mariadb connector swap (in progress) * update CMakeLists, add preprocessor definition to switch between mysql and mariadb connectors * update types with missing aarch64 check * corrected adding extra flag to properly compile mariadbconn in CMakeLists * updated readme with arm builds section * fix build failure if test folder does not exist * Remove mysql connector from all builds, add mariadbconnector to windows build * readd Linux check for backtrace lib to CMakeLists.txt * Separate system specific mariadbconncpp extra compile flags * Copy dlls to exes directory once built * fetch prebuilt binaries on windows so that ClangCL can be used * Delay load dll so that plugin directory is set correctly * Fixed typo in glibcxx compile flag * whitespacing, spaces -> tabs * Updated README.md, included instructions to update * Updated README.md added libssl-dev requirement and removed mysql connector references from macOS builds section * apple compile fixes for zlib and shared library name * add windows arm64 checks to raknet * Setup plugins directory for the connector to search in, pass openssl_root_dir on for apple * Fix copy paths for single config generators and non windows * change plugin folder location, another single config generator fix * GENERATOR_IS_MULTI_CONFIG is a property not a variable * Fixed a few errors after merge * Fix plugin directory path, force windows to look at the right folder * fixed directory name for make_directory command * Update README.md Updated MacOS, Windows build instructions. * set INSTALL_PLUGINDIR so that the right directory is used * Support for relative rpath for docker build * Rebase on main * Remove extra git submodule * Update CMakeLists.txt * Remove CMakeLists.txt file from mariadb Remove the CMakeLists.txt file from the mariaDBConnector so we dont build the tests. Also add a config option to the CMakeVariables.txt so you can build the connector with multiple jobs * Compile on windows Specify the mariadbcpp.dll file location with a defined absolute path so windows knows it actually exists. * default to 1 job Default mariadb jobs running in parallel to 1 instead of 4 * Move mariadbcpp.dll file to the expected directory on windows * Changed plugin Updated the plugin location from the project binary directory to the expected location, the mariadb binary directory. * Addressed windows dll issues by moving files to the expected directory instead of a directory that wouldnt get created * Update README Co-authored-by: Aaron Kimbrell <aronwk.aaron@gmail.com> Co-authored-by: EmosewaMC <39972741+EmosewaMC@users.noreply.github.com>
2022-07-04 04:33:05 +00:00
}