mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-02 10:53:44 +00:00
feat: property reputation from visitors, resistant to farming
Property worlds now give their property reputation for the time other people spend on it, which fills the property lists and the news screen's Today's Top Properties. Visitors are counted per account; the owner's account, accounts linked to it and staff don't count. A visit earns nothing for the first property_reputation_min_visit seconds (WorldConfig's propertyReputationDelay), then each active minute (the visitor moved) earns reputationPerMinute times a multiplier, for a capped number of minutes per visit. Repeat visitors earn less the more recent days they already gave reputation, and each visitor and each property have a daily cap. Every parameter is a setting; what each account gave each property per day is kept in property_reputation_visits. The rules are pure functions with unit tests. Fixes #636 Fixes #637 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -215,6 +215,12 @@ public:
|
||||
std::vector<ZoneLimit> GetZoneLimits() override;
|
||||
void SetZoneLimit(const ZoneLimit& limit) override;
|
||||
void DeleteZoneLimit(uint32_t zoneId) override;
|
||||
// IPropertyReputation
|
||||
VisitorHistory GetPropertyVisitorHistory(LWOOBJID propertyId, uint32_t accountId, uint32_t day, uint32_t days) override;
|
||||
int64_t GetPropertyReputationOnDay(LWOOBJID propertyId, uint32_t day) override;
|
||||
void AddPropertyReputation(LWOOBJID propertyId, uint32_t accountId, uint32_t day, int64_t points, int64_t seconds) override;
|
||||
nlohmann::json GetPropertyReputationDays(LWOOBJID propertyId, uint32_t fromDay) override;
|
||||
|
||||
// IPropertyRent
|
||||
std::vector<RentRate> GetPropertyRentRates() override;
|
||||
void SetPropertyRentRate(const RentRate& rate) override;
|
||||
|
||||
@@ -20,6 +20,7 @@ set(DDATABASES_DATABASES_MYSQL_TABLES_SOURCES
|
||||
"FeaturedProperties.cpp"
|
||||
"Contraband.cpp"
|
||||
"PropertyRent.cpp"
|
||||
"PropertyReputation.cpp"
|
||||
"MessageCaptures.cpp"
|
||||
"ChatLog.cpp"
|
||||
"RelatedData.cpp"
|
||||
|
||||
39
dDatabase/GameDatabase/MySQL/Tables/PropertyReputation.cpp
Normal file
39
dDatabase/GameDatabase/MySQL/Tables/PropertyReputation.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "MySQLDatabase.h"
|
||||
|
||||
IPropertyReputation::VisitorHistory MySQLDatabase::GetPropertyVisitorHistory(LWOOBJID propertyId, uint32_t accountId, uint32_t day, uint32_t days) {
|
||||
VisitorHistory history;
|
||||
auto result = ExecuteSelect(
|
||||
"SELECT COALESCE(SUM(CASE WHEN day = ? THEN points ELSE 0 END), 0) AS today, "
|
||||
"COALESCE(SUM(CASE WHEN day < ? AND points > 0 THEN 1 ELSE 0 END), 0) AS previous_days "
|
||||
"FROM property_reputation_visits WHERE property_id = ? AND account_id = ? AND day >= ? AND day <= ?;",
|
||||
day, day, propertyId, accountId, day >= days ? day - days : 0, day);
|
||||
if (result->next()) {
|
||||
history.today = result->getInt64("today");
|
||||
history.previousDays = static_cast<uint32_t>(result->getInt64("previous_days"));
|
||||
}
|
||||
return history;
|
||||
}
|
||||
|
||||
int64_t MySQLDatabase::GetPropertyReputationOnDay(LWOOBJID propertyId, uint32_t day) {
|
||||
auto result = ExecuteSelect("SELECT COALESCE(SUM(points), 0) AS points FROM property_reputation_visits WHERE property_id = ? AND day = ?;", propertyId, day);
|
||||
return result->next() ? result->getInt64("points") : 0;
|
||||
}
|
||||
|
||||
void MySQLDatabase::AddPropertyReputation(LWOOBJID propertyId, uint32_t accountId, uint32_t day, int64_t points, int64_t seconds) {
|
||||
ExecuteInsert(
|
||||
"INSERT INTO property_reputation_visits (property_id, account_id, day, points, seconds) VALUES (?, ?, ?, ?, ?) "
|
||||
"ON DUPLICATE KEY UPDATE points = points + VALUES(points), seconds = seconds + VALUES(seconds);",
|
||||
propertyId, accountId, day, points, seconds);
|
||||
if (points > 0) ExecuteUpdate("UPDATE properties SET reputation = reputation + ? WHERE id = ?;", points, propertyId);
|
||||
}
|
||||
|
||||
nlohmann::json MySQLDatabase::GetPropertyReputationDays(LWOOBJID propertyId, uint32_t fromDay) {
|
||||
auto result = ExecuteSelect(
|
||||
"SELECT day, COUNT(*) AS visitors, SUM(points) AS points, SUM(seconds) AS seconds FROM property_reputation_visits "
|
||||
"WHERE property_id = ? AND day >= ? GROUP BY day ORDER BY day DESC;", propertyId, fromDay);
|
||||
nlohmann::json days = nlohmann::json::array();
|
||||
while (result->next()) {
|
||||
days.push_back({ {"day", result->getInt("day")}, {"visitors", result->getInt64("visitors")}, {"points", result->getInt64("points")}, {"seconds", result->getInt64("seconds")} });
|
||||
}
|
||||
return days;
|
||||
}
|
||||
Reference in New Issue
Block a user