Skip to content

Commit

Permalink
feat: store history detail
Browse files Browse the repository at this point in the history
  • Loading branch information
dudantas committed Sep 17, 2024
1 parent 30cc334 commit 6635d63
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 47 deletions.
8 changes: 4 additions & 4 deletions src/creatures/players/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7784,13 +7784,13 @@ void Player::setStoreHistory(const StoreHistory &history) {
storeHistoryVector.push_back(history);
}

void Player::addStoreHistory(bool fromMarket, uint64_t createdAt, MarketAction_t actionType, uint32_t coinAmount, CoinType coinType, HistoryTypes_t historyType, const std::string &description, const std::string &playerName, uint64_t totalPrice) {
void Player::addStoreHistory(bool fromMarket, uint64_t createdAt, uint32_t coinAmount, HistoryTypes_t historyType, const std::string &description, const std::string &playerName, uint64_t totalPrice /* = 0*/) {
StoreHistory storeHistory;
storeHistory.fromMarket = fromMarket;
storeHistory.createdAt = createdAt;
storeHistory.coinAmount = actionType == MARKETACTION_SELL ? static_cast<int32_t>(coinAmount) * -1 : coinAmount;
storeHistory.coinType = coinType;
storeHistory.historyType = historyType;
storeHistory.coinAmount = historyType == HistoryTypes_t::GIFT ? static_cast<int32_t>(coinAmount) * -1 : coinAmount;
storeHistory.coinType = CoinType::Transferable;
storeHistory.historyType = HistoryTypes_t::NONE;
storeHistory.description = description;
storeHistory.playerName = playerName;
storeHistory.totalPrice = totalPrice;
Expand Down
2 changes: 1 addition & 1 deletion src/creatures/players/player.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2675,7 +2675,7 @@ class Player final : public Creature, public Cylinder, public Bankable {
void sendStoreError(StoreErrors_t errorType, std::string errorMessage);
std::vector<StoreHistory> &getStoreHistory();
void setStoreHistory(const StoreHistory &history);
void addStoreHistory(bool fromMarket, uint64_t createdAt, MarketAction_t actionType, uint32_t coinAmount, CoinType coinType, HistoryTypes_t historyType, const std::string &description, const std::string &playerName, uint64_t totalPrice);
void addStoreHistory(bool fromMarket, uint64_t createdAt, uint32_t coinAmount, HistoryTypes_t historyType, const std::string &description, const std::string &playerName, uint64_t totalPrice = 0);
bool canBuyStoreOffer(const Offer* offer);

private:
Expand Down
19 changes: 10 additions & 9 deletions src/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9100,7 +9100,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
"Sold on Market"
);

player->addStoreHistory(true, createdAt, MARKETACTION_SELL, amount, CoinType::Transferable, HistoryTypes_t::NONE, "Sold via the Market", player->getName(), totalPrice);
player->addStoreHistory(true, createdAt, amount, HistoryTypes_t::GIFT, "Transferred via the Market", player->getName(), totalPrice);
} else {
if (!removeOfferItems(player, depotLocker, it, amount, offer.tier, offerStatus)) {
g_logger().error("[{}] failed to remove item with id {}, from player {}, errorcode: {}", __FUNCTION__, it.id, player->getName(), offerStatus.str());
Expand All @@ -9126,7 +9126,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16

if (it.id == ITEM_STORE_COIN) {
buyerPlayer->getAccount()->addCoins(enumToValue(CoinType::Transferable), amount, "Purchased on Market");
buyerPlayer->addStoreHistory(true, createdAt, MARKETACTION_BUY, amount, CoinType::Transferable, HistoryTypes_t::NONE, "Purchased via the Market", buyerPlayer->getName(), totalPrice);
buyerPlayer->addStoreHistory(true, createdAt, amount, HistoryTypes_t::REFUND, "Purchased via the Market", buyerPlayer->getName(), totalPrice);
} else if (it.stackable) {
uint16_t tmpAmount = amount;
while (tmpAmount > 0) {
Expand Down Expand Up @@ -9198,7 +9198,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16

if (it.id == ITEM_STORE_COIN) {
player->getAccount()->addCoins(enumToValue(CoinType::Transferable), amount, "Purchased on Market");
player->addStoreHistory(true, createdAt, MARKETACTION_BUY, amount, CoinType::Transferable, HistoryTypes_t::NONE, "Purchased via the Market", player->getName(), totalPrice);
player->addStoreHistory(true, createdAt, amount, HistoryTypes_t::REFUND, "Purchased via the Market", player->getName(), totalPrice);
} else if (it.stackable) {
uint16_t tmpAmount = amount;
while (tmpAmount > 0) {
Expand Down Expand Up @@ -9255,7 +9255,7 @@ void Game::playerAcceptMarketOffer(uint32_t playerId, uint32_t timestamp, uint16
const auto &tranferable = enumToValue(CoinType::Transferable);
const auto &removeCoin = enumToValue(CoinTransactionType::Remove);
sellerPlayer->getAccount()->registerCoinTransaction(removeCoin, tranferable, amount, "Sold on Market");
sellerPlayer->addStoreHistory(true, createdAt, MARKETACTION_SELL, amount, CoinType::Transferable, HistoryTypes_t::NONE, "Sold via the Market", sellerPlayer->getName(), totalPrice);
sellerPlayer->addStoreHistory(true, createdAt, amount, HistoryTypes_t::GIFT, "Transferred via the Market", sellerPlayer->getName(), totalPrice);
}

if (it.id != ITEM_STORE_COIN) {
Expand Down Expand Up @@ -10562,7 +10562,7 @@ void Game::playerOpenStore(uint32_t playerId) {
player->openStore();
}

void Game::playerCoinTransfer(uint32_t playerId, const std::string receptorName, uint32_t coinAmount) {
void Game::playerCoinTransfer(uint32_t playerId, const std::string &receptorName, uint32_t coinAmount) {
std::shared_ptr<Player> playerDonator = getPlayerByID(playerId);
if (!playerDonator) {
return;
Expand Down Expand Up @@ -10594,8 +10594,8 @@ void Game::playerCoinTransfer(uint32_t playerId, const std::string receptorName,
playerDonator->getAccount()->removeCoins(enumToValue(CoinType::Transferable), coinAmount, historyDesc);
playerReceptor->getAccount()->addCoins(enumToValue(CoinType::Transferable), coinAmount, historyDesc);

playerDonator->addStoreHistory(false, createdAt, MARKETACTION_SELL, coinAmount, CoinType::Transferable, HistoryTypes_t::NONE, historyDesc, playerReceptor->getName(), 0);
playerReceptor->addStoreHistory(false, createdAt, MARKETACTION_BUY, coinAmount, CoinType::Transferable, HistoryTypes_t::NONE, historyDesc, playerReceptor->getName(), 0);
playerDonator->addStoreHistory(false, createdAt, coinAmount, HistoryTypes_t::GIFT, historyDesc, playerReceptor->getName());
playerReceptor->addStoreHistory(false, createdAt, coinAmount, HistoryTypes_t::NONE, historyDesc, playerReceptor->getName());
playerReceptor->sendCoinBalance();
playerDonator->openStore();
playerDonator->updateUIExhausted();
Expand Down Expand Up @@ -10904,8 +10904,9 @@ void Game::playerBuyStoreOffer(uint32_t playerId, const Offer* offer, std::strin
player->sendStoreSuccess(returnmessage);

auto offerAmount = offer->getOfferCount();
g_logger().trace("[{}] offer price {}, offer ammount {}, price per item {}", __METHOD_NAME__, offerPrice, offerAmount, offerPrice / offerAmount);
player->addStoreHistory(true, getTimeNow(), MARKETACTION_SELL, offerPrice, CoinType::Transferable, HistoryTypes_t::NONE, offer->getOfferName(), player->getName(), offerPrice / offerAmount);
auto pricePerItem = offerPrice ? offerPrice / offerAmount : 0;
g_logger().trace("[{}] offer price {}, offer ammount {}, price per item {}", __METHOD_NAME__, offerPrice, offerAmount, pricePerItem);
player->addStoreHistory(false, getTimeNow(), offerPrice, HistoryTypes_t::GIFT, offer->getOfferName(), player->getName());
} else {
player->sendStoreError(StoreErrors_t::PURCHASE, "An error has occurred, please contact your administrator.");
}
Expand Down
2 changes: 1 addition & 1 deletion src/game/game.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ class Game {

// Store Functions
void playerOpenStore(uint32_t playerId);
void playerCoinTransfer(uint32_t playerId, const std::string receptorName, uint32_t coinAmount);
void playerCoinTransfer(uint32_t playerId, const std::string &receptorName, uint32_t coinAmount);
void playerOpenStoreHistory(uint32_t playerId, uint32_t page);
void playerBuyStoreOffer(uint32_t playerId, const Offer* offer, std::string newName, uint8_t sexId);
// Process Offers
Expand Down
25 changes: 14 additions & 11 deletions src/io/io_store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -335,11 +335,10 @@ const std::vector<std::string> IOStore::getOffersDisableReasonVector() {
return offersDisableReason;
}

StoreHistoryDetail IOStore::getStoreHistoryDetail(const std::string &playerName, bool fromMarket, uint32_t createdAt) {
StoreHistoryDetail details;
StoreHistoryDetail IOStore::getStoreHistoryDetail(const std::string &playerName, uint32_t createdAt, bool hasDetail) {
std::string query = fmt::format(
"SELECT * FROM `store_history` WHERE `player_name` = '{}' AND `created_at` = '{}' AND `show_detail` = {}",
playerName, createdAt, 1
"SELECT * FROM `store_history` WHERE `player_name` = {} AND `created_at` = {} AND `show_detail` = {}",
g_database().escapeString(playerName), createdAt, static_cast<uint8_t>(hasDetail)
);

DBResult_ptr result = Database::getInstance().storeQuery(query);
Expand All @@ -348,12 +347,16 @@ StoreHistoryDetail IOStore::getStoreHistoryDetail(const std::string &playerName,
return {};
}

details.createdAt = createdAt;
details.description = result->getString("description");
details.coinAmount = result->getNumber<uint32_t>("coin_amount");
details.playerName = result->getString("player_name");
details.totalPrice = result->getNumber<uint32_t>("total_price");
return details;
StoreHistoryDetail storeDetail;
storeDetail.historyType = result->getNumber<HistoryTypes_t>("type");
storeDetail.createdAt = createdAt;
storeDetail.coinAmount = result->getNumber<int32_t>("coin_amount");
storeDetail.description = result->getString("description");
storeDetail.playerName = result->getString("player_name");
storeDetail.totalPrice = result->getNumber<uint32_t>("total_price");

g_logger().debug("Store details for creation data: {}, description '{}', player '{}', coin amount '{}', total price '{}'", storeDetail.createdAt, storeDetail.description, storeDetail.playerName, storeDetail.coinAmount, storeDetail.totalPrice);
return storeDetail;
}

// Category Class functions
Expand Down Expand Up @@ -387,7 +390,7 @@ void Category::addOffer(const Offer* newOffer) {
}

// Offer Functions
std::vector<RelatedOffer> Offer::getRelatedOffersVector() const {
const std::vector<RelatedOffer> &Offer::getRelatedOffersVector() const {
return relatedOffers;
}
void Offer::addRelatedOffer(const RelatedOffer &relatedOffer) {
Expand Down
7 changes: 4 additions & 3 deletions src/io/io_store.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,10 @@ struct BannerInfo {
};

struct StoreHistoryDetail {
HistoryTypes_t historyType {};
uint32_t createdAt {};
int32_t coinAmount {};
uint64_t totalPrice {};
uint32_t coinAmount {};
std::string description {};
std::string playerName {};
};
Expand Down Expand Up @@ -210,7 +211,7 @@ class IOStore {
std::vector<Offer> getOffersContainingSubstring(const std::string &searchString);
Offer* getOfferByName(const std::string &searchString);

static StoreHistoryDetail getStoreHistoryDetail(const std::string &playerName, bool fromMarket, uint32_t createdAt);
static StoreHistoryDetail getStoreHistoryDetail(const std::string &playerName, uint32_t createdAt, bool hasDetail);

private:
IOStore() = default;
Expand Down Expand Up @@ -339,7 +340,7 @@ class Offer {
return movable;
}

std::vector<RelatedOffer> getRelatedOffersVector() const;
const std::vector<RelatedOffer> &getRelatedOffersVector() const;
void addRelatedOffer(const RelatedOffer &relatedOffer);

private:
Expand Down
42 changes: 24 additions & 18 deletions src/server/network/protocol/protocolgame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9333,11 +9333,11 @@ void ProtocolGame::parseRequestStoreOffers(NetworkMessage &msg) {

void ProtocolGame::sendOfferBytes(NetworkMessage &msg, const Offer* offer) {
msg.addString(offer->getOfferName());
const auto relatedOffersVector = offer->getRelatedOffersVector();
const auto &relatedOffersVector = offer->getRelatedOffersVector();
auto offersCount = getVectorIterationIncreaseCount(relatedOffersVector);
msg.addByte(static_cast<uint8_t>(offersCount)); // Related Offers inside a Base Offer
sendOfferDescription(offer);
for (const auto relatedOffer : relatedOffersVector) {
for (const auto &relatedOffer : relatedOffersVector) {
msg.add<uint32_t>(relatedOffer.id);
msg.add<uint16_t>(relatedOffer.count);

Expand Down Expand Up @@ -9683,26 +9683,32 @@ void ProtocolGame::parseStoreDetail(NetworkMessage &msg) {

auto createdAt = msg.get<uint32_t>();
if (createdAt != 0) {
g_logger().info("Details creation data: {}, player '{}'", createdAt, player->getName());
// Get the offer by creation data and send the details structure based on offer details
// Get the offer by creation data
auto storeDetail = g_ioStore().getStoreHistoryDetail(player->getName(), createdAt, true);
g_logger().info("Store details for creation data: {}, description '{}', player '{}', coin amount '{}', total price '{}'", storeDetail.createdAt, storeDetail.description, storeDetail.playerName, storeDetail.coinAmount, storeDetail.totalPrice);

/*
// Send store detail structure ?
NetworkMessage newMsg;
newMsg.addByte(???);
newMsg.add<uint32_t>(createdData);
newMsg.addString(storeDetail.description);
newMsg.addString(storeDetail.playerName);
newMsg.add<uint32_t>(storeDetail.coinAmount);
newMsg.add<uint32_t>(storeDetail.totalPrice / storeDetail.coinAmount); // Price per coin
newMsg.add<uint64_t(storeDetail.totalPrice);
writeToOutputBuffer(newMsg);
*/
if (storeDetail.createdAt != createdAt) {
g_logger().error("Store detail not found for creation data: {}, player '{}'", createdAt, player->getName());
return;
}

sendStoreDetail(storeDetail);
}
}

void ProtocolGame::sendStoreDetail(const StoreHistoryDetail &storeDetail) {
auto pricePerCoin = storeDetail.totalPrice ? storeDetail.totalPrice / storeDetail.coinAmount : 0;

NetworkMessage newMsg;
newMsg.addByte(0xCB);
newMsg.add<uint32_t>(storeDetail.createdAt);
newMsg.addByte(enumToValue(storeDetail.historyType));
newMsg.addString(storeDetail.description);
newMsg.addString(storeDetail.playerName);
newMsg.add<int32_t>(storeDetail.coinAmount);
newMsg.add<uint64_t>(pricePerCoin);
newMsg.add<int64_t>(storeDetail.totalPrice);
writeToOutputBuffer(newMsg);
}

void ProtocolGame::sendDisableLoginMusic() {
if (oldProtocol || !player || player->getOperatingSystem() >= CLIENTOS_OTCLIENT_LINUX) {
return;
Expand Down
2 changes: 2 additions & 0 deletions src/server/network/protocol/protocolgame.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ struct ModalWindow;
struct Achievement;
struct Badge;
struct Title;
struct StoreHistoryDetail;

using ProtocolGame_ptr = std::shared_ptr<ProtocolGame>;

Expand Down Expand Up @@ -504,6 +505,7 @@ class ProtocolGame final : public Protocol {
void parseSaveWheel(NetworkMessage &msg);
void parseWheelGemAction(NetworkMessage &msg);
void parseStoreDetail(NetworkMessage &msg);
void sendStoreDetail(const StoreHistoryDetail &storeDetail);

friend class Player;
friend class PlayerWheel;
Expand Down

0 comments on commit 6635d63

Please sign in to comment.