Skip to content

Commit

Permalink
Merge branch 'main' into luan/fix-bestiary
Browse files Browse the repository at this point in the history
  • Loading branch information
elsongabriel authored Dec 11, 2023
2 parents b43c3f1 + 029fee6 commit 29f85fc
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 40 deletions.
1 change: 0 additions & 1 deletion data-otservbr-global/monster/magicals/manticore.lua
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ monster.loot = {
{ name = "royal star", chance = 1010, maxCount = 3 },
{ name = "wand of everblazing", chance = 1010 },
{ name = "magma legs", chance = 340 },
spread = 1,
}

monster.attacks = {
Expand Down
41 changes: 15 additions & 26 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ void Game::start(ServiceManager* manager) {
g_dispatcher().cycleEvent(
EVENT_LUA_GARBAGE_COLLECTION, [this] { g_luaEnvironment().collectGarbage(); }, "Calling GC"
);
g_dispatcher().cycleEvent(EVENT_REFRESH_MARKET_PRICES, std::bind_front(&Game::loadItemsPrice, this), "Game::loadItemsPrice");
}

GameState_t Game::getGameState() const {
Expand Down Expand Up @@ -388,7 +389,7 @@ void Game::setGameState(GameState_t newState) {
}

bool Game::loadItemsPrice() {
itemsSaleCount = 0;
IOMarket::getInstance().updateStatistics();
std::ostringstream query, marketQuery;
query << "SELECT DISTINCT `itemtype` FROM `market_offers`;";

Expand All @@ -398,20 +399,19 @@ bool Game::loadItemsPrice() {
return false;
}

do {
marketQuery.str(std::string());
uint16_t itemId = result->getNumber<uint16_t>("itemtype");
marketQuery << "SELECT `price`, `tier` FROM `market_offers` WHERE `itemtype` = " << itemId << " ORDER BY `price` DESC LIMIT 1";
DBResult_ptr marketOffersResult = db.storeQuery(marketQuery.str());
if (marketOffersResult) {
std::map<uint8_t, uint64_t> tierAndCount;
auto tier = marketOffersResult->getNumber<uint8_t>("tier");
auto price = marketOffersResult->getNumber<uint64_t>("price");
tierAndCount[tier] = price;
itemsPriceMap[itemId] = tierAndCount;
itemsSaleCount++;
}
} while (result->next());
auto stats = IOMarket::getInstance().getPurchaseStatistics();
for (const auto &[itemId, itemStats] : stats) {
std::map<uint8_t, uint64_t> tierToPrice;
for (const auto &[tier, tierStats] : itemStats) {
auto averagePrice = tierStats.totalPrice / tierStats.numTransactions;
tierToPrice[tier] = averagePrice;
}
itemsPriceMap[itemId] = tierToPrice;
}
auto offers = IOMarket::getInstance().getActiveOffers(MARKETACTION_BUY);
for (const auto &offer : offers) {
itemsPriceMap[offer.itemId][offer.tier] = std::max(itemsPriceMap[offer.itemId][offer.tier], offer.price);
}

return true;
}
Expand Down Expand Up @@ -8523,17 +8523,6 @@ void Game::playerCreateMarketOffer(uint32_t playerId, uint8_t type, uint16_t ite

IOMarket::createOffer(player->getGUID(), static_cast<MarketAction_t>(type), it.id, amount, price, tier, anonymous);

// uint8_t = tier, uint64_t price
std::map<uint8_t, uint64_t> tierAndPriceMap;
tierAndPriceMap[tier] = price;
auto ColorItem = itemsPriceMap.find(it.id);
if (ColorItem == itemsPriceMap.end()) {
itemsPriceMap[it.id] = tierAndPriceMap;
itemsSaleCount++;
} else if (auto priceIt = ColorItem->second.find(tier); priceIt->second < price) {
itemsPriceMap[it.id] = tierAndPriceMap;
}

const MarketOfferList &buyOffers = IOMarket::getActiveOffers(MARKETACTION_BUY, it.id, tier);
const MarketOfferList &sellOffers = IOMarket::getActiveOffers(MARKETACTION_SELL, it.id, tier);
player->sendMarketBrowseItem(it.id, buyOffers, sellOffers, tier);
Expand Down
5 changes: 1 addition & 4 deletions src/game/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ static constexpr int32_t EVENT_DECAYINTERVAL = 250;
static constexpr int32_t EVENT_DECAY_BUCKETS = 4;
static constexpr int32_t EVENT_FORGEABLEMONSTERCHECKINTERVAL = 300000;
static constexpr int32_t EVENT_LUA_GARBAGE_COLLECTION = 60000 * 10; // 10min
static constexpr int32_t EVENT_REFRESH_MARKET_PRICES = 60000; // 1min

static constexpr std::chrono::minutes CACHE_EXPIRATION_TIME { 10 }; // 10min
static constexpr std::chrono::minutes HIGHSCORE_CACHE_EXPIRATION_TIME { 10 }; // 10min
Expand Down Expand Up @@ -184,9 +185,6 @@ class Game {
uint32_t getPlayersRecord() const {
return playersRecord;
}
uint16_t getItemsPriceCount() const {
return itemsSaleCount;
}

void addItemsClassification(ItemClassification* itemsClassification) {
itemsClassifications.push_back(itemsClassification);
Expand Down Expand Up @@ -860,7 +858,6 @@ class Game {
uint32_t motdNum = 0;

std::map<uint16_t, std::map<uint8_t, uint64_t>> itemsPriceMap;
uint16_t itemsSaleCount;

std::vector<ItemClassification*> itemsClassifications;

Expand Down
29 changes: 29 additions & 0 deletions src/io/iomarket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,35 @@ uint8_t IOMarket::getTierFromDatabaseTable(const std::string &string) {
return tier;
}

MarketOfferList IOMarket::getActiveOffers(MarketAction_t action) {
MarketOfferList offerList;

std::ostringstream query;
query << "SELECT `id`, `amount`, `price`, `tier`, `created`, `anonymous`, (SELECT `name` FROM `players` WHERE `id` = `player_id`) AS `player_name` FROM `market_offers` WHERE `sale` = " << action;

DBResult_ptr result = Database::getInstance().storeQuery(query.str());
if (!result) {
return offerList;
}

const int32_t marketOfferDuration = g_configManager().getNumber(MARKET_OFFER_DURATION, __FUNCTION__);

do {
MarketOffer offer;
offer.amount = result->getNumber<uint16_t>("amount");
offer.price = result->getNumber<uint64_t>("price");
offer.timestamp = result->getNumber<uint32_t>("created") + marketOfferDuration;
offer.counter = result->getNumber<uint32_t>("id") & 0xFFFF;
if (result->getNumber<uint16_t>("anonymous") == 0) {
offer.playerName = result->getString("player_name");
} else {
offer.playerName = "Anonymous";
}
offer.tier = getTierFromDatabaseTable(result->getString("tier"));
offerList.push_back(offer);
} while (result->next());
return offerList;
}
MarketOfferList IOMarket::getActiveOffers(MarketAction_t action, uint16_t itemId, uint8_t tier) {
MarketOfferList offerList;

Expand Down
1 change: 1 addition & 0 deletions src/io/iomarket.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class IOMarket {
return inject<IOMarket>();
}

static MarketOfferList getActiveOffers(MarketAction_t action);
static MarketOfferList getActiveOffers(MarketAction_t action, uint16_t itemId, uint8_t tier);
static MarketOfferList getOwnOffers(MarketAction_t action, uint32_t playerId);
static HistoryMarketOfferList getOwnHistory(MarketAction_t action, uint32_t playerId);
Expand Down
21 changes: 12 additions & 9 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7802,18 +7802,21 @@ void ProtocolGame::sendItemsPrice() {
NetworkMessage msg;
msg.addByte(0xCD);

msg.add<uint16_t>(g_game().getItemsPriceCount());
if (g_game().getItemsPriceCount() > 0) {
for (const auto &[itemId, tierAndPriceMap] : g_game().getItemsPrice()) {
for (const auto &[tier, price] : tierAndPriceMap) {
msg.add<uint16_t>(itemId);
if (Item::items[itemId].upgradeClassification > 0) {
msg.addByte(tier);
}
msg.add<uint64_t>(price);
auto countBuffer = msg.getBufferPosition();
uint16_t count = 0;
msg.skipBytes(2);
for (const auto &[itemId, tierAndPriceMap] : g_game().getItemsPrice()) {
for (const auto &[tier, price] : tierAndPriceMap) {
msg.add<uint16_t>(itemId);
if (Item::items[itemId].upgradeClassification > 0) {
msg.addByte(tier);
}
msg.add<uint64_t>(price);
count++;
}
}
msg.setBufferPosition(countBuffer);
msg.add<uint16_t>(count);

writeToOutputBuffer(msg);
}
Expand Down

0 comments on commit 29f85fc

Please sign in to comment.