395 lines
10 KiB
C++
395 lines
10 KiB
C++
#include <std_include.hpp>
|
|
#include "../dw_include.hpp"
|
|
|
|
#include "game/game.hpp"
|
|
|
|
#include "steam/steam.hpp"
|
|
|
|
#include "utils/json.hpp"
|
|
|
|
namespace demonware
|
|
{
|
|
bdMarketplace::bdMarketplace() : service(80, "bdMarketplace")
|
|
{
|
|
this->register_task(42, &bdMarketplace::startExchangeTransaction);
|
|
this->register_task(43, &bdMarketplace::purchaseOnSteamInitialize);
|
|
this->register_task(44, &bdMarketplace::purchaseOnSteamFinalize);
|
|
this->register_task(49, &bdMarketplace::getExpiredInventoryItems);
|
|
this->register_task(58, &bdMarketplace::validateInventoryItemsToken);
|
|
this->register_task(60, &bdMarketplace::steamProcessDurable);
|
|
this->register_task(85, &bdMarketplace::steamProcessDurableV2);
|
|
this->register_task(106, &bdMarketplace::purchaseSkus);
|
|
this->register_task(130, &bdMarketplace::getBalance);
|
|
this->register_task(132, &bdMarketplace::getBalanceV2);
|
|
this->register_task(165, &bdMarketplace::getInventoryPaginated);
|
|
this->register_task(193, &bdMarketplace::putPlayersInventoryItems);
|
|
this->register_task(199, &bdMarketplace::pawnItems);
|
|
this->register_task(232, &bdMarketplace::getEntitlements);
|
|
}
|
|
|
|
void bdMarketplace::startExchangeTransaction(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
class bdStartExchangeTransactionResult final : public bdTaskResult
|
|
{
|
|
public:
|
|
std::string m_exchangeTransactionId;
|
|
|
|
void serialize(byte_buffer* data) override
|
|
{
|
|
data->write_string(m_exchangeTransactionId);
|
|
}
|
|
};
|
|
|
|
std::string platform;
|
|
buffer->read_string(&platform);
|
|
|
|
auto reply = server->create_reply(this->task_id());
|
|
auto info = std::make_unique<bdStartExchangeTransactionResult>();
|
|
info->m_exchangeTransactionId = std::to_string(service_reply::transaction_id);
|
|
reply.add(info);
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::purchaseOnSteamInitialize(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
/*class bdPurchaseInitializeResult final : public bdTaskResult
|
|
{
|
|
public:
|
|
std::uint64_t m_orderId;
|
|
|
|
void serialize(byte_buffer* data) override
|
|
{
|
|
data->write_uint64(m_orderId);
|
|
}
|
|
};
|
|
|
|
std::string platform;
|
|
std::string m_exchangeTransactionId;
|
|
std::uint32_t skuId;
|
|
std::string language;
|
|
std::uint64_t userID;
|
|
std::string contextUser;
|
|
|
|
buffer->read_string(&platform);
|
|
buffer->read_string(&m_exchangeTransactionId);
|
|
buffer->read_uint32(&skuId);
|
|
buffer->read_string(&language);
|
|
buffer->read_uint64(&userID);
|
|
buffer->read_string(&contextUser);
|
|
|
|
auto reply = server->create_reply(this->task_id());
|
|
auto info = std::make_unique<bdPurchaseInitializeResult>();
|
|
info->m_orderId = 0; // would need to emulate steam microtransaction stuff...
|
|
reply.add(info);
|
|
reply.send();*/
|
|
|
|
server->create_reply(this->task_id(), BD_MARKETPLACE_STEAM_NOT_APPROVED).send();
|
|
}
|
|
|
|
void bdMarketplace::purchaseOnSteamFinalize(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::getExpiredInventoryItems(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::validateInventoryItemsToken(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::steamProcessDurable(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::steamProcessDurableV2(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
std::string platform;
|
|
buffer->read_string(&platform);
|
|
|
|
std::string unk1;
|
|
buffer->read_string(&unk1);
|
|
|
|
std::uint32_t unk2;
|
|
buffer->read_uint32(&unk2);
|
|
|
|
std::uint64_t unk3;
|
|
buffer->read_uint64(&unk3);
|
|
|
|
std::string unk4;
|
|
buffer->read_string(&unk4);
|
|
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::purchaseSkus(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
std::string platform, clientTransactionId;
|
|
uint32_t numSkuIds;
|
|
uint32_t skuIds[4]{};
|
|
uint32_t numQuanities;
|
|
uint32_t skuQuanities[4]{};
|
|
uint32_t numMaxResults;
|
|
uint32_t numDiscounts;
|
|
uint32_t skuDiscounts[4]{};
|
|
uint32_t numCouponRecipients;
|
|
// coupon data here
|
|
uint32_t numCouponMetadata;
|
|
// coupon metadata here
|
|
uint8_t customSourceType;
|
|
bool ignoreEntitlements;
|
|
|
|
buffer->read_string(&platform);
|
|
buffer->read_string(&clientTransactionId);
|
|
|
|
buffer->read_uint32(&numSkuIds);
|
|
assert(numSkuIds < 4);
|
|
|
|
for (auto i = 0u; i < numSkuIds; i++)
|
|
{
|
|
buffer->read_uint32(&skuIds[i]);
|
|
}
|
|
|
|
buffer->read_uint32(&numQuanities);
|
|
assert(numQuanities < 4);
|
|
|
|
for (auto i = 0u; i < numQuanities; i++)
|
|
{
|
|
buffer->read_uint32(&skuQuanities[i]);
|
|
}
|
|
|
|
buffer->read_uint32(&numMaxResults);
|
|
|
|
buffer->read_uint32(&numDiscounts);
|
|
assert(numDiscounts < 4);
|
|
|
|
for (auto i = 0u; i < numDiscounts; i++)
|
|
{
|
|
buffer->read_uint32(&skuDiscounts[i]);
|
|
}
|
|
|
|
buffer->read_uint32(&numCouponRecipients);
|
|
assert(numCouponRecipients == 0);
|
|
|
|
buffer->read_uint32(&numCouponMetadata);
|
|
assert(numCouponMetadata == 0);
|
|
|
|
buffer->read_ubyte(&customSourceType);
|
|
buffer->read_bool(&ignoreEntitlements);
|
|
|
|
assert(numSkuIds == 1);
|
|
|
|
auto id = skuIds[0];
|
|
auto num = skuQuanities[0];
|
|
|
|
// schematic buy comes through here
|
|
if (id < 70000 || id > 75223)
|
|
{
|
|
const auto item = loot::get_loot(id);
|
|
const auto cost = item.cost;
|
|
const auto item_balance = loot::get_item_balance(id);
|
|
const auto currency_balance = loot::get_currency_balance(loot::CurrencyType::salvage);
|
|
|
|
if (cost > currency_balance)
|
|
{
|
|
server->create_reply(this->task_id(), BD_MARKETPLACE_ERROR).send();
|
|
return;
|
|
}
|
|
|
|
loot::set_currency_balance(loot::CurrencyType::salvage, currency_balance - cost);
|
|
loot::set_item_balance(id, item_balance + num);
|
|
|
|
loot::save();
|
|
|
|
server->create_reply(this->task_id(), BD_NO_ERROR).send();
|
|
return;
|
|
}
|
|
|
|
int currency_id = loot::CurrencyType::keys;
|
|
if (id > 70000 && (id - 5000) >= 70000)
|
|
{
|
|
id = id - 5000;
|
|
currency_id = loot::CurrencyType::codpoints;
|
|
}
|
|
|
|
const auto current_balance = loot::get_currency_balance(currency_id);
|
|
const auto cost = loot::get_lootcrate_cost(id, currency_id);
|
|
|
|
if (cost > current_balance)
|
|
{
|
|
server->create_reply(this->task_id(), BD_MARKETPLACE_ERROR).send();
|
|
return;
|
|
}
|
|
|
|
loot::set_currency_balance(currency_id, current_balance - cost);
|
|
loot::set_item_balance(id, loot::get_item_balance(id) + num);
|
|
|
|
loot::save();
|
|
|
|
server->create_reply(this->task_id(), BD_NO_ERROR).send();
|
|
}
|
|
|
|
void bdMarketplace::getBalance(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::getBalanceV2(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
std::string platform;
|
|
buffer->read_string(&platform);
|
|
|
|
std::uint32_t maxNumResults;
|
|
buffer->read_uint32(&maxNumResults);
|
|
|
|
auto reply = server->create_reply(this->task_id());
|
|
|
|
std::uint32_t numResults = 0;
|
|
|
|
auto add_result = [&](std::uint8_t id, std::uint32_t value)
|
|
{
|
|
if (numResults >= maxNumResults) return;
|
|
auto info = std::make_unique<bdMarketplaceCurrency>();
|
|
info->m_currencyId = id;
|
|
info->m_value = value;
|
|
reply.add(info);
|
|
numResults++;
|
|
};
|
|
|
|
add_result(loot::CurrencyType::keys, loot::get_currency_balance(loot::CurrencyType::keys));
|
|
add_result(loot::CurrencyType::salvage, loot::get_currency_balance(loot::CurrencyType::salvage));
|
|
add_result(loot::CurrencyType::codpoints, loot::get_currency_balance(loot::CurrencyType::codpoints));
|
|
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::getInventoryPaginated(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
if (game::environment::is_dedi())
|
|
{
|
|
server->create_reply(this->task_id()).send();
|
|
return;
|
|
}
|
|
|
|
std::string platform;
|
|
std::uint32_t itemsPerPage, pageNum;
|
|
|
|
buffer->read_string(&platform);
|
|
buffer->read_uint32(&pageNum);
|
|
buffer->read_uint32(&itemsPerPage);
|
|
|
|
assert(itemsPerPage);
|
|
|
|
static unsigned int paginated_index = 0;
|
|
|
|
auto reply = server->create_reply(this->task_id());
|
|
|
|
auto all_loot = loot::get_all_loot_owned();
|
|
|
|
const unsigned int index = paginated_index;
|
|
for (size_t i = 0; i < all_loot.size() - index; i++)
|
|
{
|
|
const auto loot = all_loot[paginated_index];
|
|
const auto balance = loot::get_item_balance(loot.id);
|
|
assert(balance);
|
|
|
|
auto info = std::make_unique<bdMarketplaceInventory>();
|
|
|
|
info->m_playerId = steam::SteamUser()->GetSteamID().bits;
|
|
info->unk = "";
|
|
info->m_itemId = loot.id;
|
|
info->m_itemQuantity = balance;
|
|
info->m_itemXp = 0;
|
|
info->m_itemData = "";
|
|
info->m_expireDateTime = 0;
|
|
info->m_expiryDuration = 0;
|
|
info->m_collisionField = 0;
|
|
info->m_modDateTime = 0;
|
|
|
|
reply.add(info);
|
|
|
|
paginated_index++;
|
|
if (i >= itemsPerPage - 1)
|
|
{
|
|
reply.send();
|
|
return;
|
|
}
|
|
}
|
|
|
|
paginated_index = 0;
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::putPlayersInventoryItems(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::pawnItems(service_server* server, byte_buffer* buffer) const
|
|
{
|
|
std::string platform, clientTransactionId;
|
|
std::uint32_t numItemsToPawn;
|
|
|
|
buffer->read_string(&platform);
|
|
buffer->read_string(&clientTransactionId);
|
|
|
|
auto currency = loot::get_currency_balance(loot::CurrencyType::salvage);
|
|
|
|
buffer->read_uint32(&numItemsToPawn);
|
|
for (auto i = 0u; i < numItemsToPawn; i++)
|
|
{
|
|
std::uint32_t id, nextBalance;
|
|
std::uint16_t unk2; // collision?
|
|
|
|
buffer->read_uint32(&id);
|
|
buffer->read_uint32(&nextBalance);
|
|
buffer->read_uint16(&unk2);
|
|
|
|
const auto loot = loot::get_loot(id);
|
|
const auto amount = loot::get_item_balance(loot.id);
|
|
|
|
if (amount == 1) // why are you trying to pawn when we only have 1...
|
|
{
|
|
continue;
|
|
}
|
|
|
|
loot::set_item_balance(loot.id, nextBalance);
|
|
currency += loot.salvageReturned;
|
|
|
|
#ifdef DW_DEBUG
|
|
printf("[DW]: pawning %d for %d salvage\n", loot.id, loot.salvageReturned);
|
|
#endif
|
|
}
|
|
loot::set_currency_balance(loot::CurrencyType::salvage, currency);
|
|
loot::save();
|
|
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
|
|
void bdMarketplace::getEntitlements(service_server* server, byte_buffer* /*buffer*/) const
|
|
{
|
|
// TODO:
|
|
auto reply = server->create_reply(this->task_id());
|
|
reply.send();
|
|
}
|
|
}
|