mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-07-01 09:10:01 +00:00
remove complex queries and move logic to dDatabase
remove unused code Use correct id fix arrows use correct parameter fix queries Update Property.cpp remove unused header remove extra include
This commit is contained in:
parent
de3fe93100
commit
bf61ae8984
@ -73,4 +73,4 @@ cpp_space_around_assignment_operator=insert
|
||||
cpp_space_pointer_reference_alignment=left
|
||||
cpp_space_around_ternary_operator=insert
|
||||
cpp_wrap_preserve_blocks=one_liners
|
||||
cpp_indent_comment=fasle
|
||||
cpp_indent_comment=false
|
||||
|
11
dCommon/dEnums/ePropertySortType.h
Normal file
11
dCommon/dEnums/ePropertySortType.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef EPROPERTYSORTTYPE_H
|
||||
#define EPROPERTYSORTTYPE_H
|
||||
|
||||
enum ePropertySortType : int32_t {
|
||||
SORT_TYPE_FRIENDS = 0,
|
||||
SORT_TYPE_REPUTATION = 1,
|
||||
SORT_TYPE_RECENT = 3,
|
||||
SORT_TYPE_FEATURED = 5
|
||||
};
|
||||
|
||||
#endif //!EPROPERTYSORTTYPE_H
|
@ -4,6 +4,8 @@
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
enum ePropertySortType : int32_t;
|
||||
|
||||
class IProperty {
|
||||
public:
|
||||
struct Info {
|
||||
@ -18,11 +20,33 @@ public:
|
||||
uint32_t lastUpdatedTime{};
|
||||
uint32_t claimedTime{};
|
||||
uint32_t reputation{};
|
||||
float performanceCost{};
|
||||
};
|
||||
|
||||
struct PropertyLookup {
|
||||
uint32_t mapId{};
|
||||
std::string searchString;
|
||||
ePropertySortType sortChoice{};
|
||||
uint32_t playerId{};
|
||||
uint32_t numResults{};
|
||||
uint32_t startIndex{};
|
||||
uint32_t playerSort{};
|
||||
};
|
||||
|
||||
struct PropertyEntranceResult {
|
||||
int32_t totalEntriesMatchingQuery{};
|
||||
// The entries that match the query. This should only contain up to 12 entries.
|
||||
std::vector<IProperty::Info> entries;
|
||||
};
|
||||
|
||||
// Get the property info for the given property id.
|
||||
virtual std::optional<IProperty::Info> GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) = 0;
|
||||
|
||||
// Get the properties for the given property lookup params.
|
||||
// This is expected to return a result set of up to 12 properties
|
||||
// so as not to transfer too much data at once.
|
||||
virtual std::optional<IProperty::PropertyEntranceResult> GetProperties(const PropertyLookup& params) = 0;
|
||||
|
||||
// Update the property moderation info for the given property id.
|
||||
virtual void UpdatePropertyModerationInfo(const IProperty::Info& info) = 0;
|
||||
|
||||
|
@ -112,6 +112,7 @@ public:
|
||||
std::string GetBehavior(const int32_t behaviorId) override;
|
||||
void RemoveBehavior(const int32_t characterId) override;
|
||||
void UpdateAccountGmLevel(const uint32_t accountId, const eGameMasterLevel gmLevel) override;
|
||||
std::optional<IProperty::PropertyEntranceResult> GetProperties(const IProperty::PropertyLookup& params) override;
|
||||
private:
|
||||
|
||||
// Generic query functions that can be used for any query.
|
||||
|
@ -1,8 +1,140 @@
|
||||
#include "MySQLDatabase.h"
|
||||
#include "ePropertySortType.h"
|
||||
|
||||
std::optional<IProperty::PropertyEntranceResult> MySQLDatabase::GetProperties(const IProperty::PropertyLookup& params) {
|
||||
std::optional<IProperty::PropertyEntranceResult> result;
|
||||
std::string query;
|
||||
std::unique_ptr<sql::ResultSet> properties;
|
||||
|
||||
if (params.sortChoice == SORT_TYPE_FEATURED || params.sortChoice == SORT_TYPE_FRIENDS) {
|
||||
query = R"QUERY(
|
||||
FROM properties as p
|
||||
JOIN charinfo as ci
|
||||
ON ci.prop_clone_id = p.clone_id
|
||||
where p.zone_id = ?
|
||||
AND (
|
||||
p.description LIKE ?
|
||||
OR p.name LIKE ?
|
||||
OR ci.name LIKE ?
|
||||
)
|
||||
AND p.privacy_option >= ?
|
||||
AND p.owner_id IN (
|
||||
SELECT fr.requested_player AS player FROM (
|
||||
SELECT CASE
|
||||
WHEN player_id = ? THEN friend_id
|
||||
WHEN friend_id = ? THEN player_id
|
||||
END AS requested_player FROM friends
|
||||
) AS fr
|
||||
JOIN charinfo AS ci ON ci.id = fr.requested_player
|
||||
WHERE fr.requested_player IS NOT NULL AND fr.requested_player != ?
|
||||
) ORDER BY ci.name ASC
|
||||
)QUERY";
|
||||
const auto completeQuery = "SELECT p.* " + query + " LIMIT ? OFFSET ?;";
|
||||
properties = ExecuteSelect(
|
||||
completeQuery,
|
||||
params.mapId,
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
params.playerSort,
|
||||
params.playerId,
|
||||
params.playerId,
|
||||
params.playerId,
|
||||
params.numResults,
|
||||
params.startIndex
|
||||
);
|
||||
const auto countQuery = "SELECT COUNT(*) as count" + query + ";";
|
||||
auto count = ExecuteSelect(
|
||||
countQuery,
|
||||
params.mapId,
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
params.playerSort,
|
||||
params.playerId,
|
||||
params.playerId,
|
||||
params.playerId
|
||||
);
|
||||
if (count->next()) {
|
||||
result->totalEntriesMatchingQuery = count->getUInt("count");
|
||||
}
|
||||
} else {
|
||||
if (params.sortChoice == SORT_TYPE_REPUTATION) {
|
||||
query = R"QUERY(
|
||||
FROM properties as p
|
||||
JOIN charinfo as ci
|
||||
ON ci.prop_clone_id = p.clone_id
|
||||
where p.zone_id = ?
|
||||
AND (
|
||||
p.description LIKE ?
|
||||
OR p.name LIKE ?
|
||||
OR ci.name LIKE ?
|
||||
)
|
||||
AND p.privacy_option >= ?
|
||||
ORDER BY p.reputation DESC, p.last_updated DESC
|
||||
)QUERY";
|
||||
} else {
|
||||
query = R"QUERY(
|
||||
FROM properties as p
|
||||
JOIN charinfo as ci
|
||||
ON ci.prop_clone_id = p.clone_id
|
||||
where p.zone_id = ?
|
||||
AND (
|
||||
p.description LIKE ?
|
||||
OR p.name LIKE ?
|
||||
OR ci.name LIKE ?
|
||||
)
|
||||
AND p.privacy_option >= ?
|
||||
ORDER BY p.last_updated DESC
|
||||
)QUERY";
|
||||
}
|
||||
const auto completeQuery = "SELECT p.* " + query + " LIMIT ? OFFSET ?;";
|
||||
properties = ExecuteSelect(
|
||||
completeQuery,
|
||||
params.mapId,
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
params.playerSort,
|
||||
params.numResults,
|
||||
params.startIndex
|
||||
);
|
||||
const auto countQuery = "SELECT COUNT(*) as count" + query + ";";
|
||||
auto count = ExecuteSelect(
|
||||
countQuery,
|
||||
params.mapId,
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
"%" + params.searchString + "%",
|
||||
params.playerSort
|
||||
);
|
||||
if (count->next()) {
|
||||
result->totalEntriesMatchingQuery = count->getUInt("count");
|
||||
}
|
||||
}
|
||||
|
||||
while (properties->next()) {
|
||||
auto& entry = result->entries.emplace_back();
|
||||
entry.id = properties->getUInt64("id");
|
||||
entry.ownerId = properties->getUInt64("owner_id");
|
||||
entry.cloneId = properties->getUInt64("clone_id");
|
||||
entry.name = properties->getString("name").c_str();
|
||||
entry.description = properties->getString("description").c_str();
|
||||
entry.privacyOption = properties->getInt("privacy_option");
|
||||
entry.rejectionReason = properties->getString("rejection_reason").c_str();
|
||||
entry.lastUpdatedTime = properties->getUInt("last_updated");
|
||||
entry.claimedTime = properties->getUInt("time_claimed");
|
||||
entry.reputation = properties->getUInt("reputation");
|
||||
entry.modApproved = properties->getUInt("mod_approved");
|
||||
entry.performanceCost = properties->getFloat("performance_cost");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID mapId, const LWOCLONEID cloneId) {
|
||||
auto propertyEntry = ExecuteSelect(
|
||||
"SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved "
|
||||
"SELECT id, owner_id, clone_id, name, description, privacy_option, rejection_reason, last_updated, time_claimed, reputation, mod_approved, performance_cost "
|
||||
"FROM properties WHERE zone_id = ? AND clone_id = ?;", mapId, cloneId);
|
||||
|
||||
if (!propertyEntry->next()) {
|
||||
@ -21,6 +153,7 @@ std::optional<IProperty::Info> MySQLDatabase::GetPropertyInfo(const LWOMAPID map
|
||||
toReturn.claimedTime = propertyEntry->getUInt("time_claimed");
|
||||
toReturn.reputation = propertyEntry->getUInt("reputation");
|
||||
toReturn.modApproved = propertyEntry->getUInt("mod_approved");
|
||||
toReturn.performanceCost = propertyEntry->getFloat("performance_cost");
|
||||
|
||||
return toReturn;
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public:
|
||||
User& operator=(const User& other);
|
||||
bool operator==(const User& other) const;
|
||||
|
||||
uint32_t GetAccountID() { return m_AccountID; }
|
||||
uint32_t GetAccountID() const { return m_AccountID; }
|
||||
std::string& GetUsername() { return m_Username; }
|
||||
std::string& GetSessionKey() { return m_SessionKey; }
|
||||
SystemAddress& GetSystemAddress() { return m_SystemAddress; }
|
||||
|
@ -14,6 +14,8 @@
|
||||
#include "Amf3.h"
|
||||
#include "eObjectBits.h"
|
||||
#include "eGameMasterLevel.h"
|
||||
#include "ePropertySortType.h"
|
||||
#include "User.h"
|
||||
|
||||
PropertyEntranceComponent::PropertyEntranceComponent(Entity* parent, uint32_t componentID) : Component(parent) {
|
||||
this->propertyQueries = {};
|
||||
@ -74,261 +76,103 @@ void PropertyEntranceComponent::OnEnterProperty(Entity* entity, uint32_t index,
|
||||
launcher->Launch(entity, launcher->GetTargetZone(), cloneId);
|
||||
}
|
||||
|
||||
PropertySelectQueryProperty PropertyEntranceComponent::SetPropertyValues(PropertySelectQueryProperty property, LWOCLONEID cloneId, std::string ownerName, std::string propertyName, std::string propertyDescription, float reputation, bool isBFF, bool isFriend, bool isModeratorApproved, bool isAlt, bool isOwned, uint32_t privacyOption, uint32_t timeLastUpdated, float performanceCost) {
|
||||
property.CloneId = cloneId;
|
||||
property.OwnerName = ownerName;
|
||||
property.Name = propertyName;
|
||||
property.Description = propertyDescription;
|
||||
property.Reputation = reputation;
|
||||
property.IsBestFriend = isBFF;
|
||||
property.IsFriend = isFriend;
|
||||
property.IsModeratorApproved = isModeratorApproved;
|
||||
property.IsAlt = isAlt;
|
||||
property.IsOwned = isOwned;
|
||||
property.AccessType = privacyOption;
|
||||
property.DateLastPublished = timeLastUpdated;
|
||||
property.PerformanceCost = performanceCost;
|
||||
|
||||
return property;
|
||||
}
|
||||
|
||||
std::string PropertyEntranceComponent::BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery, bool wantLimits) {
|
||||
std::string base;
|
||||
if (customQuery == "") {
|
||||
base = baseQueryForProperties;
|
||||
} else {
|
||||
base = customQuery;
|
||||
}
|
||||
std::string orderBy = "";
|
||||
if (sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS) {
|
||||
std::string friendsList = " AND p.owner_id IN (";
|
||||
|
||||
auto friendsListQuery = Database::Get()->CreatePreppedStmt("SELECT * FROM (SELECT CASE WHEN player_id = ? THEN friend_id WHEN friend_id = ? THEN player_id END AS requested_player FROM friends ) AS fr WHERE requested_player IS NOT NULL ORDER BY requested_player DESC;");
|
||||
|
||||
friendsListQuery->setUInt(1, character->GetID());
|
||||
friendsListQuery->setUInt(2, character->GetID());
|
||||
|
||||
auto friendsListQueryResult = friendsListQuery->executeQuery();
|
||||
|
||||
while (friendsListQueryResult->next()) {
|
||||
auto playerIDToConvert = friendsListQueryResult->getInt(1);
|
||||
friendsList = friendsList + std::to_string(playerIDToConvert) + ",";
|
||||
}
|
||||
// Replace trailing comma with the closing parenthesis.
|
||||
if (friendsList.at(friendsList.size() - 1) == ',') friendsList.erase(friendsList.size() - 1, 1);
|
||||
friendsList += ") ";
|
||||
|
||||
// If we have no friends then use a -1 for the query.
|
||||
if (friendsList.find("()") != std::string::npos) friendsList = " AND p.owner_id IN (-1) ";
|
||||
|
||||
orderBy += friendsList + "ORDER BY ci.name ASC ";
|
||||
|
||||
delete friendsListQueryResult;
|
||||
friendsListQueryResult = nullptr;
|
||||
|
||||
delete friendsListQuery;
|
||||
friendsListQuery = nullptr;
|
||||
} else if (sortMethod == SORT_TYPE_RECENT) {
|
||||
orderBy = "ORDER BY p.last_updated DESC ";
|
||||
} else if (sortMethod == SORT_TYPE_REPUTATION) {
|
||||
orderBy = "ORDER BY p.reputation DESC, p.last_updated DESC ";
|
||||
} else {
|
||||
orderBy = "ORDER BY p.last_updated DESC ";
|
||||
}
|
||||
return base + orderBy + (wantLimits ? "LIMIT ? OFFSET ?;" : ";");
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
std::vector<PropertySelectQueryProperty> entries{};
|
||||
PropertySelectQueryProperty playerEntry{};
|
||||
|
||||
auto character = entity->GetCharacter();
|
||||
const auto* const character = entity->GetCharacter();
|
||||
if (!character) return;
|
||||
const auto* const user = character->GetParentUser();
|
||||
if (!user) return;
|
||||
|
||||
auto& entries = propertyQueries[entity->GetObjectID()];
|
||||
entries.clear();
|
||||
// Player property goes in index 1 of the vector. This is how the client expects it.
|
||||
auto playerPropertyLookup = Database::Get()->CreatePreppedStmt("SELECT * FROM properties WHERE owner_id = ? AND zone_id = ?");
|
||||
|
||||
playerPropertyLookup->setInt(1, character->GetID());
|
||||
playerPropertyLookup->setInt(2, this->m_MapID);
|
||||
|
||||
auto playerPropertyLookupResults = playerPropertyLookup->executeQuery();
|
||||
const auto playerProperty = Database::Get()->GetPropertyInfo(m_MapID, character->GetPropertyCloneID());
|
||||
|
||||
// If the player has a property this query will have a single result.
|
||||
if (playerPropertyLookupResults->next()) {
|
||||
const auto cloneId = playerPropertyLookupResults->getUInt64(4);
|
||||
const auto propertyName = std::string(playerPropertyLookupResults->getString(5).c_str());
|
||||
const auto propertyDescription = std::string(playerPropertyLookupResults->getString(6).c_str());
|
||||
const auto privacyOption = playerPropertyLookupResults->getInt(9);
|
||||
const auto modApproved = playerPropertyLookupResults->getBoolean(10);
|
||||
const auto dateLastUpdated = playerPropertyLookupResults->getInt64(11);
|
||||
const auto reputation = playerPropertyLookupResults->getUInt(14);
|
||||
const auto performanceCost = playerPropertyLookupResults->getFloat(16);
|
||||
|
||||
playerEntry = SetPropertyValues(playerEntry, cloneId, character->GetName(), propertyName, propertyDescription, reputation, true, true, modApproved, true, true, privacyOption, dateLastUpdated, performanceCost);
|
||||
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;
|
||||
} else {
|
||||
playerEntry = SetPropertyValues(playerEntry, character->GetPropertyCloneID(), character->GetName(), "", "", 0, true, true);
|
||||
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;
|
||||
}
|
||||
|
||||
delete playerPropertyLookupResults;
|
||||
playerPropertyLookupResults = nullptr;
|
||||
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;
|
||||
|
||||
delete playerPropertyLookup;
|
||||
playerPropertyLookup = nullptr;
|
||||
|
||||
entries.push_back(playerEntry);
|
||||
|
||||
const auto query = BuildQuery(entity, sortMethod, character);
|
||||
|
||||
auto propertyLookup = Database::Get()->CreatePreppedStmt(query);
|
||||
|
||||
const auto searchString = "%" + filterText + "%";
|
||||
propertyLookup->setUInt(1, this->m_MapID);
|
||||
propertyLookup->setString(2, searchString.c_str());
|
||||
propertyLookup->setString(3, searchString.c_str());
|
||||
propertyLookup->setString(4, searchString.c_str());
|
||||
propertyLookup->setInt(5, sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? static_cast<uint32_t>(PropertyPrivacyOption::Friends) : static_cast<uint32_t>(PropertyPrivacyOption::Public));
|
||||
propertyLookup->setInt(6, numResults);
|
||||
propertyLookup->setInt(7, startIndex);
|
||||
|
||||
auto propertyEntry = propertyLookup->executeQuery();
|
||||
|
||||
while (propertyEntry->next()) {
|
||||
const auto propertyId = propertyEntry->getUInt64(1);
|
||||
const auto owner = propertyEntry->getInt(2);
|
||||
const auto cloneId = propertyEntry->getUInt64(4);
|
||||
const auto propertyNameFromDb = std::string(propertyEntry->getString(5).c_str());
|
||||
const auto propertyDescriptionFromDb = std::string(propertyEntry->getString(6).c_str());
|
||||
const auto privacyOption = propertyEntry->getInt(9);
|
||||
const auto modApproved = propertyEntry->getBoolean(10);
|
||||
const auto dateLastUpdated = propertyEntry->getInt(11);
|
||||
const float reputation = propertyEntry->getInt(14);
|
||||
const auto performanceCost = propertyEntry->getFloat(16);
|
||||
|
||||
PropertySelectQueryProperty entry{};
|
||||
|
||||
std::string ownerName = "";
|
||||
bool isOwned = true;
|
||||
auto nameLookup = Database::Get()->CreatePreppedStmt("SELECT name FROM charinfo WHERE prop_clone_id = ?;");
|
||||
|
||||
nameLookup->setUInt64(1, cloneId);
|
||||
|
||||
auto nameResult = nameLookup->executeQuery();
|
||||
|
||||
if (!nameResult->next()) {
|
||||
delete nameLookup;
|
||||
nameLookup = nullptr;
|
||||
|
||||
LOG("Failed to find property owner name for %llu!", cloneId);
|
||||
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);
|
||||
continue;
|
||||
} else {
|
||||
isOwned = cloneId == character->GetPropertyCloneID();
|
||||
ownerName = std::string(nameResult->getString(1).c_str());
|
||||
}
|
||||
auto& entry = entries.emplace_back();
|
||||
|
||||
delete nameResult;
|
||||
nameResult = nullptr;
|
||||
|
||||
delete nameLookup;
|
||||
nameLookup = nullptr;
|
||||
|
||||
std::string propertyName = propertyNameFromDb;
|
||||
std::string propertyDescription = propertyDescriptionFromDb;
|
||||
|
||||
bool isBestFriend = false;
|
||||
bool isFriend = false;
|
||||
|
||||
// Convert owner char id to LWOOBJID
|
||||
LWOOBJID ownerObjId = owner;
|
||||
GeneralUtils::SetBit(ownerObjId, eObjectBits::CHARACTER);
|
||||
GeneralUtils::SetBit(ownerObjId, eObjectBits::PERSISTENT);
|
||||
|
||||
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;
|
||||
// Query to get friend and best friend fields
|
||||
auto friendCheck = Database::Get()->CreatePreppedStmt("SELECT best_friend FROM friends WHERE (player_id = ? AND friend_id = ?) OR (player_id = ? AND friend_id = ?)");
|
||||
|
||||
friendCheck->setUInt(1, character->GetID());
|
||||
friendCheck->setUInt(2, ownerObjId);
|
||||
friendCheck->setUInt(3, ownerObjId);
|
||||
friendCheck->setUInt(4, character->GetID());
|
||||
|
||||
auto friendResult = friendCheck->executeQuery();
|
||||
|
||||
const auto friendCheck = Database::Get()->GetBestFriendStatus(character->GetID(), owner);
|
||||
// If we got a result than the two players are friends.
|
||||
if (friendResult->next()) {
|
||||
isFriend = true;
|
||||
if (friendResult->getInt(1) == 3) {
|
||||
isBestFriend = true;
|
||||
}
|
||||
if (friendCheck.has_value()) {
|
||||
entry.IsFriend = true;
|
||||
entry.IsBestFriend = friendCheck->bestFriendStatus == 3;
|
||||
}
|
||||
|
||||
delete friendCheck;
|
||||
friendCheck = nullptr;
|
||||
|
||||
delete friendResult;
|
||||
friendResult = nullptr;
|
||||
|
||||
bool isModeratorApproved = propertyEntry->getBoolean(10);
|
||||
|
||||
if (!isModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
|
||||
propertyName = "[AWAITING APPROVAL]";
|
||||
propertyDescription = "[AWAITING APPROVAL]";
|
||||
isModeratorApproved = true;
|
||||
if (!entry.IsModeratorApproved && entity->GetGMLevel() >= eGameMasterLevel::LEAD_MODERATOR) {
|
||||
entry.Name = "[AWAITING APPROVAL]";
|
||||
entry.Description = "[AWAITING APPROVAL]";
|
||||
entry.IsModeratorApproved = true;
|
||||
}
|
||||
|
||||
bool isAlt = false;
|
||||
// Query to determine whether this property is an alt character of the entity.
|
||||
auto isAltQuery = Database::Get()->CreatePreppedStmt("SELECT id FROM charinfo where account_id in (SELECT account_id from charinfo WHERE id = ?) AND id = ?;");
|
||||
|
||||
isAltQuery->setInt(1, character->GetID());
|
||||
isAltQuery->setInt(2, owner);
|
||||
|
||||
auto isAltQueryResults = isAltQuery->executeQuery();
|
||||
|
||||
if (isAltQueryResults->next()) {
|
||||
isAlt = true;
|
||||
for (const auto charid : Database::Get()->GetAccountCharacterIds(user->GetAccountID())) {
|
||||
entry.IsAlt = charid == owner;
|
||||
if (entry.IsAlt) break;
|
||||
}
|
||||
|
||||
delete isAltQueryResults;
|
||||
isAltQueryResults = nullptr;
|
||||
|
||||
delete isAltQuery;
|
||||
isAltQuery = nullptr;
|
||||
|
||||
entry = SetPropertyValues(entry, cloneId, ownerName, propertyName, propertyDescription, reputation, isBestFriend, isFriend, isModeratorApproved, isAlt, isOwned, privacyOption, dateLastUpdated, performanceCost);
|
||||
|
||||
entries.push_back(entry);
|
||||
}
|
||||
|
||||
delete propertyEntry;
|
||||
propertyEntry = nullptr;
|
||||
|
||||
delete propertyLookup;
|
||||
propertyLookup = nullptr;
|
||||
|
||||
propertyQueries[entity->GetObjectID()] = entries;
|
||||
|
||||
// Query here is to figure out whether or not to display the button to go to the next page or not.
|
||||
int32_t numberOfProperties = 0;
|
||||
|
||||
auto buttonQuery = BuildQuery(entity, sortMethod, character, "SELECT COUNT(*) FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ", false);
|
||||
auto propertiesLeft = Database::Get()->CreatePreppedStmt(buttonQuery);
|
||||
|
||||
propertiesLeft->setUInt(1, this->m_MapID);
|
||||
propertiesLeft->setString(2, searchString.c_str());
|
||||
propertiesLeft->setString(3, searchString.c_str());
|
||||
propertiesLeft->setString(4, searchString.c_str());
|
||||
propertiesLeft->setInt(5, sortMethod == SORT_TYPE_FEATURED || sortMethod == SORT_TYPE_FRIENDS ? 1 : 2);
|
||||
|
||||
auto result = propertiesLeft->executeQuery();
|
||||
result->next();
|
||||
numberOfProperties = result->getInt(1);
|
||||
|
||||
delete result;
|
||||
result = nullptr;
|
||||
|
||||
delete propertiesLeft;
|
||||
propertiesLeft = nullptr;
|
||||
|
||||
GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, numberOfProperties - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr);
|
||||
GameMessages::SendPropertySelectQuery(m_Parent->GetObjectID(), startIndex, lookupResult->totalEntriesMatchingQuery - (startIndex + numResults) > 0, character->GetPropertyCloneID(), false, true, entries, sysAddr);
|
||||
}
|
||||
|
@ -59,10 +59,6 @@ public:
|
||||
*/
|
||||
[[nodiscard]] LWOMAPID GetMapID() const { return m_MapID; };
|
||||
|
||||
PropertySelectQueryProperty SetPropertyValues(PropertySelectQueryProperty property, LWOCLONEID cloneId = LWOCLONEID_INVALID, std::string ownerName = "", std::string propertyName = "", std::string propertyDescription = "", float reputation = 0, bool isBFF = false, bool isFriend = false, bool isModeratorApproved = false, bool isAlt = false, bool isOwned = false, uint32_t privacyOption = 0, uint32_t timeLastUpdated = 0, float performanceCost = 0.0f);
|
||||
|
||||
std::string BuildQuery(Entity* entity, int32_t sortMethod, Character* character, std::string customQuery = "", bool wantLimits = true);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Cache of property information that was queried for property launched, indexed by property ID
|
||||
@ -78,13 +74,4 @@ private:
|
||||
* The base map ID for this property (Avant Grove, etc).
|
||||
*/
|
||||
LWOMAPID m_MapID;
|
||||
|
||||
enum ePropertySortType : int32_t {
|
||||
SORT_TYPE_FRIENDS = 0,
|
||||
SORT_TYPE_REPUTATION = 1,
|
||||
SORT_TYPE_RECENT = 3,
|
||||
SORT_TYPE_FEATURED = 5
|
||||
};
|
||||
|
||||
std::string baseQueryForProperties = "SELECT p.* FROM properties as p JOIN charinfo as ci ON ci.prop_clone_id = p.clone_id where p.zone_id = ? AND (p.description LIKE ? OR p.name LIKE ? OR ci.name LIKE ?) AND p.privacy_option >= ? ";
|
||||
};
|
||||
|
@ -29,10 +29,10 @@ void PropertySelectQueryProperty::Serialize(RakNet::BitStream& stream) const {
|
||||
stream.Write(IsOwned);
|
||||
stream.Write(AccessType);
|
||||
stream.Write(DateLastPublished);
|
||||
stream.Write(PerformanceIndex);
|
||||
stream.Write(PerformanceCost);
|
||||
}
|
||||
|
||||
void PropertySelectQueryProperty::Deserialize(RakNet::BitStream& stream) const {
|
||||
// Do we need this?
|
||||
// no
|
||||
}
|
||||
|
@ -5,8 +5,7 @@
|
||||
|
||||
#include "Entity.h"
|
||||
|
||||
class PropertySelectQueryProperty final
|
||||
{
|
||||
class PropertySelectQueryProperty final {
|
||||
public:
|
||||
void Serialize(RakNet::BitStream& stream) const;
|
||||
|
||||
@ -23,9 +22,8 @@ public:
|
||||
bool IsAlt = false; // Whether or not the property is owned by an alt of the account owner
|
||||
bool IsOwned = false; // Whether or not the property is owned
|
||||
uint32_t AccessType = 0; // The privacy option of the property
|
||||
uint32_t DateLastPublished = 0; // The last day the property was published
|
||||
uint64_t DateLastPublished = 0; // The last day the property was published
|
||||
float PerformanceCost = 0; // The performance cost of the property
|
||||
uint32_t PerformanceIndex = 0; // The performance index of the property? Always 0?
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user