remove custom item amount field, it is now redundant

since we track supply for all items
This commit is contained in:
Crypto City 2020-10-09 15:56:17 +00:00
parent 9586a32958
commit f7bd04fc12
34 changed files with 139 additions and 171 deletions

View File

@ -2037,11 +2037,10 @@ public:
virtual void set_cc_special_events(uint32_t city, const std::vector<cc::special_event_data_t> &sed) = 0;
virtual void get_cc_special_events(uint32_t city, std::vector<cc::special_event_data_t> &sed) const = 0;
virtual uint32_t allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data) = 0;
virtual uint32_t allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data) = 0;
virtual void delete_cc_custom_item(uint32_t id) = 0;
virtual bool get_cc_custom_item_data(uint32_t id, cc::cc_custom_item_t &cid) const = 0;
virtual void set_cc_custom_item_ignore(uint32_t id, bool ignore) = 0;
virtual void set_cc_custom_item_amount(uint32_t id, uint32_t amount) = 0;
virtual bool for_all_cc_custom_items(std::function<bool(const cc::cc_custom_item_t &cid)> f) const = 0;
virtual uint32_t allocate_new_cc_event_badge(const std::string &name, const std::string &desc) = 0;

View File

@ -651,15 +651,14 @@ typedef struct mdb_cc_special_event_data
typedef struct mdb_cc_custom_item_data_t
{
uint32_t amount;
uint32_t creator;
uint64_t creation_height;
uint32_t creator;
uint32_t group;
uint64_t user_data[NUM_CUSTOM_ITEM_USER_DATA];
uint8_t ignore: 1;
uint8_t is_group: 1;
uint8_t is_public: 1;
uint8_t padding: 5;
uint64_t user_data[NUM_CUSTOM_ITEM_USER_DATA];
char name[MAX_CC_NAME_LENGTH];
char primary_description[MAX_CC_DESCRIPTION_LENGTH];
char secondary_description[MAX_CC_DESCRIPTION_LENGTH];
@ -8457,7 +8456,7 @@ void BlockchainLMDB::get_cc_special_events(uint32_t city, std::vector<cc::specia
TXN_POSTFIX_RDONLY();
}
uint32_t BlockchainLMDB::allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data)
uint32_t BlockchainLMDB::allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
@ -8494,7 +8493,6 @@ uint32_t BlockchainLMDB::allocate_new_cc_custom_item(uint32_t amount, uint32_t c
MINFO("Item ID " << item_id << " is available");
mdb_cc_custom_item_data_t id;
id.amount = amount;
id.creator = creator;
id.creation_height = creation_height;
id.is_group = is_group;
@ -8565,7 +8563,6 @@ bool BlockchainLMDB::get_cc_custom_item_data(uint32_t id, cc::cc_custom_item_t &
const mdb_cc_custom_item_data_t *item_data = (const mdb_cc_custom_item_data_t *)v.mv_data;
cid.id = id;
cid.amount = item_data->amount;
cid.creator = item_data->creator;
cid.creation_height = item_data->creation_height;
cid.ignore = item_data->ignore;
@ -8619,33 +8616,6 @@ void BlockchainLMDB::set_cc_custom_item_ignore(uint32_t id, bool ignore)
throw0(DB_ERROR(lmdb_error("Failed to add custom iten data to db transaction: ", result).c_str()));
}
void BlockchainLMDB::set_cc_custom_item_amount(uint32_t id, uint32_t amount)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
mdb_txn_cursors *m_cursors = &m_wcursors;
CURSOR(cc_custom_items)
// find item id
MDB_val_set(k, id);
MDB_val v;
int result = mdb_cursor_get(m_cur_cc_custom_items, &k, &v, MDB_SET);
if (result)
throw0(DB_ERROR(lmdb_error("Item " + std::to_string(id) + " not found: ", result).c_str()));
if (v.mv_size < sizeof(mdb_cc_custom_item_data_t))
throw0(DB_ERROR("Unexpected custom item data size"));
mdb_cc_custom_item_data_t cid = *(const mdb_cc_custom_item_data_t*)v.mv_data;
cid.amount = amount;
v.mv_data = (void*)&cid;
v.mv_size = sizeof(cid);
result = mdb_cursor_put(m_cur_cc_custom_items, &k, &v, 0);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add custom iten data to db transaction: ", result).c_str()));
}
bool BlockchainLMDB::for_all_cc_custom_items(std::function<bool(const cc::cc_custom_item_t &cid)> f) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
@ -8675,7 +8645,6 @@ bool BlockchainLMDB::for_all_cc_custom_items(std::function<bool(const cc::cc_cus
cc::cc_custom_item_t cid;
cid.id = id;
cid.amount = item_data.amount;
cid.creator = item_data.creator;
cid.creation_height = item_data.creation_height;
cid.ignore = item_data.ignore;

View File

@ -587,11 +587,10 @@ private:
void set_cc_special_events(uint32_t city, const std::vector<cc::special_event_data_t> &sed);
void get_cc_special_events(uint32_t city, std::vector<cc::special_event_data_t> &sed) const;
uint32_t allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data);
uint32_t allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data);
void delete_cc_custom_item(uint32_t id);
bool get_cc_custom_item_data(uint32_t id, cc::cc_custom_item_t &cid) const;
void set_cc_custom_item_ignore(uint32_t id, bool ignore);
void set_cc_custom_item_amount(uint32_t id, uint32_t amount);
bool for_all_cc_custom_items(std::function<bool(const cc::cc_custom_item_t &cid)> f) const;
uint32_t allocate_new_cc_event_badge(const std::string &name, const std::string &desc);

View File

@ -264,11 +264,10 @@ public:
virtual void set_cc_special_events(uint32_t city, const std::vector<cc::special_event_data_t> &sed) {}
virtual void get_cc_special_events(uint32_t city, std::vector<cc::special_event_data_t> &sed) const {}
virtual uint32_t allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data) { return 0; }
virtual uint32_t allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data) { return 0; }
virtual void delete_cc_custom_item(uint32_t id) {}
virtual bool get_cc_custom_item_data(uint32_t id, cc::cc_custom_item_t &cid) const { return false; }
virtual void set_cc_custom_item_ignore(uint32_t id, bool ignore) {}
virtual void set_cc_custom_item_amount(uint32_t id, uint32_t amount) {}
virtual bool for_all_cc_custom_items(std::function<bool(const cc::cc_custom_item_t &cid)> f) const { return true; }
virtual uint32_t allocate_new_cc_event_badge(const std::string &name, const std::string &desc) { return 0; }

View File

@ -1657,7 +1657,7 @@ bool add_init_state(cryptonote::BlockchainDB &db)
// coins item group
std::vector<uint64_t> user_data(NUM_CUSTOM_ITEM_USER_DATA, 0);
uint32_t coins_group_id = db.allocate_new_cc_custom_item(0, GAME_ACCOUNT, 0, "Commemorative coins", true, false, ITEM_NONE, "Commemorative coins are issued for noteworthy events in Townforge history", "", user_data);
uint32_t coins_group_id = db.allocate_new_cc_custom_item(GAME_ACCOUNT, 0, "Commemorative coins", true, false, ITEM_NONE, "Commemorative coins are issued for noteworthy events in Townforge history", "", user_data);
if (coins_group_id != COINS_ITEM_GROUP)
{
MERROR("Failed to setup coins item group");
@ -1666,7 +1666,7 @@ bool add_init_state(cryptonote::BlockchainDB &db)
// mortgages item group
user_data = std::vector<uint64_t>(NUM_CUSTOM_ITEM_USER_DATA, 0);
uint32_t mortgages_group_id = db.allocate_new_cc_custom_item(0, GAME_ACCOUNT, 0, "Mortgages", true, false, ITEM_NONE, "Mortgages allow a player to raise gold using property as security", "", user_data);
uint32_t mortgages_group_id = db.allocate_new_cc_custom_item(GAME_ACCOUNT, 0, "Mortgages", true, false, ITEM_NONE, "Mortgages allow a player to raise gold using property as security", "", user_data);
if (mortgages_group_id != MORTGAGE_ITEM_GROUP)
{
MERROR("Failed to setup mortgages item group");
@ -1676,7 +1676,7 @@ bool add_init_state(cryptonote::BlockchainDB &db)
// coins
std::string name, desc;
user_data[0] = MAKE_COLLECTIBLE_COIN_EVENT_USER_DATA_0();
uint32_t coin_settlement_id = db.allocate_new_cc_custom_item(0, GAME_ACCOUNT, 0, "Townforge genesis coin", false, false, COINS_ITEM_GROUP, "Issued to celebrate the birth of Townforge", "", user_data);
uint32_t coin_settlement_id = db.allocate_new_cc_custom_item(GAME_ACCOUNT, 0, "Townforge genesis coin", false, false, COINS_ITEM_GROUP, "Issued to celebrate the birth of Townforge", "", user_data);
if (coin_settlement_id != COIN_ITEM_SETTLEMENT)
{
MERROR("Failed to setup settlement coin");
@ -1684,7 +1684,7 @@ bool add_init_state(cryptonote::BlockchainDB &db)
}
user_data[0] = MAKE_COLLECTIBLE_COIN_YEARLY_USER_DATA_0(START_YEAR);
cc::get_collectible_coin_data(db, user_data, name, desc);
uint32_t coin_first_year = db.allocate_new_cc_custom_item(0, GAME_ACCOUNT, 0, name, false, false, COINS_ITEM_GROUP, desc, "", user_data);
uint32_t coin_first_year = db.allocate_new_cc_custom_item(GAME_ACCOUNT, 0, name, false, false, COINS_ITEM_GROUP, desc, "", user_data);
if (coin_first_year != coin_settlement_id + 1)
{
MERROR("Failed to setup first year coin");

View File

@ -138,7 +138,8 @@ uint64_t get_collectible_coin_score(const cryptonote::BlockchainDB &db, uint32_t
if (cid.is_group || cid.group != COINS_ITEM_GROUP)
continue;
const uint64_t age = height > cid.creation_height ? height - cid.creation_height : 0;
const uint32_t supply = std::min<uint32_t>(age < COINS_ITEM_GROUP ? 1000 : cid.amount, 1000);
const uint64_t amount = db.get_cc_item_count(e.first);
const uint32_t supply = std::min<uint32_t>(age < COINS_ITEM_GROUP ? 1000 : amount, 1000);
const uint32_t gold_content = get_collectible_coin_gold_content(COLLECTIBLE_COIN_TYPE(cid.user_data));
coins.push_back(std::make_tuple(e.second, supply, gold_content, age));
}

View File

@ -123,7 +123,7 @@ bool cc_command_handler_create_mortgage::execute(cryptonote::BlockchainDB &db, c
std::vector<uint64_t> user_data(NUM_CUSTOM_ITEM_USER_DATA, 0);
cc::make_mortgage_data(user_data, create_mortgage.flag, create_mortgage.item, create_mortgage.tick_payment, create_mortgage.maturity_payment, create_mortgage.maturity_height);
const uint32_t id = db.allocate_new_cc_custom_item(create_mortgage.shares, create_mortgage.cc_account, db.height() - 1, create_mortgage.name, false, true, MORTGAGE_ITEM_GROUP, create_mortgage.description, "", user_data);
const uint32_t id = db.allocate_new_cc_custom_item(create_mortgage.cc_account, db.height() - 1, create_mortgage.name, false, true, MORTGAGE_ITEM_GROUP, create_mortgage.description, "", user_data);
CHECK_AND_ASSERT_MES(id >= ITEM_FIRST_USER && id <= ITEM_LAST_USER, false, "Item creation failed");
db.set_cc_flag_mortgage(create_mortgage.flag, id);

View File

@ -70,12 +70,7 @@ bool cc_command_handler_destroy_items::check(const cryptonote::BlockchainDB &db,
std::map<uint32_t, uint32_t> item_balances;
CHECK_AND_ASSERT_MES(db.get_cc_account_item_balances(destroy_items.cc_account, item_balances), false, "Failed to get owner item balances");
if (destroy_items.item_id >= ITEM_FIRST_USER && destroy_items.item_id <= ITEM_LAST_USER)
{
cc::cc_custom_item_t cid;
CHECK_AND_ASSERT_MES(db.get_cc_custom_item_data(destroy_items.item_id, cid), false, "Failed to get custom item data");
CHECK_COMMAND_SET(cid.amount >= destroy_items.amount, tvc.m_cc_bad_amount, "Amount is higher than exists");
}
CHECK_COMMAND_SET(db.get_cc_item_count(destroy_items.item_id) >= destroy_items.amount, tvc.m_cc_bad_amount, "Amount is higher than exists");
CHECK_COMMAND_SET(item_balances[destroy_items.item_id] >= destroy_items.amount, tvc.m_cc_balance, "Destroying more items of type " << destroy_items.item_id << " than owned");
@ -93,14 +88,8 @@ bool cc_command_handler_destroy_items::execute(cryptonote::BlockchainDB &db, con
db.set_cc_account_item_balances(destroy_items.cc_account, item_balances);
CHECK_AND_ASSERT_MES(cc::decrease_item_count(db, destroy_items.item_id, destroy_items.amount), false, "Item count anomaly");
if (destroy_items.item_id >= ITEM_FIRST_USER && destroy_items.item_id <= ITEM_LAST_USER)
{
cc::cc_custom_item_t cid;
CHECK_AND_ASSERT_MES(db.get_cc_custom_item_data(destroy_items.item_id, cid), false, "Failed to get custom item data");
CHECK_AND_ASSERT_MES(cid.amount >= destroy_items.amount, false, "Amount is higher than exists");
db.set_cc_custom_item_amount(destroy_items.item_id, cid.amount - destroy_items.amount);
events.add_full(cmd, destroy_items.cc_account, 0, destroy_items.item_id, destroy_items.amount, 0) << "Destroys " << destroy_items.amount << " " << cc::get_item_name(db, destroy_items.item_id);
}
CHECK_AND_ASSERT_MES(db.get_cc_item_count(destroy_items.item_id) >= destroy_items.amount, false, "Amount is higher than exists");
events.add_full(cmd, destroy_items.cc_account, 0, destroy_items.item_id, destroy_items.amount, 0) << "Destroys " << destroy_items.amount << " " << cc::get_item_name(db, destroy_items.item_id);
return true;
}
@ -116,13 +105,7 @@ bool cc_command_handler_destroy_items::revert(cryptonote::BlockchainDB &db, cons
db.set_cc_account_item_balances(destroy_items.cc_account, item_balances);
CHECK_AND_ASSERT_MES(cc::increase_item_count(db, destroy_items.item_id, destroy_items.amount), false, "Item count anomaly");
if (destroy_items.item_id >= ITEM_FIRST_USER && destroy_items.item_id <= ITEM_LAST_USER)
{
cc::cc_custom_item_t cid;
CHECK_AND_ASSERT_MES(db.get_cc_custom_item_data(destroy_items.item_id, cid), false, "Failed to get custom item data");
CHECK_AND_ASSERT_MES(cid.amount <= std::numeric_limits<uint32_t>::max() - destroy_items.amount, false, "Amount would overflow");
db.set_cc_custom_item_amount(destroy_items.item_id, cid.amount + destroy_items.amount);
}
CHECK_AND_ASSERT_MES(db.get_cc_item_count(destroy_items.item_id) <= std::numeric_limits<uint32_t>::max() - destroy_items.amount, false, "Amount would overflow");
return true;
}

View File

@ -303,7 +303,7 @@ bool cc_command_handler_game_update::execute(cryptonote::BlockchainDB &db, const
return false;
}
cc::get_collectible_coin_data(db, e.user_data, name, desc);
db.allocate_new_cc_custom_item(0, GAME_ACCOUNT, blockchain_height - 1, std::move(name), false, false, COINS_ITEM_GROUP, std::move(desc), "", e.user_data);
db.allocate_new_cc_custom_item(GAME_ACCOUNT, blockchain_height - 1, std::move(name), false, false, COINS_ITEM_GROUP, std::move(desc), "", e.user_data);
}
for (const auto &e: game.maturing_mortgages)

View File

@ -74,7 +74,8 @@ bool cc_command_handler_mint::check(const cryptonote::BlockchainDB &db, const cr
CHECK_COMMAND_SET(!cid.is_group, tvc.m_cc_bad_item, "Invalid coin id");
CHECK_COMMAND_SET(cid.group == COINS_ITEM_GROUP, tvc.m_cc_bad_item, "Invalid coin id");
CHECK_COMMAND_SET(blockchain_height < cid.creation_height + COIN_MINTING_WINDOW, tvc.m_cc_out_of_range, "This coin is not available for minting anymore");
CHECK_COMMAND_SET(mint.amount <= std::numeric_limits<uint32_t>::max() - cid.amount, tvc.m_cc_overflow, "Number of coins would overflow");
const uint64_t amount = db.get_cc_item_count(mint.coin);
CHECK_COMMAND_SET(mint.amount <= std::numeric_limits<uint32_t>::max() - amount, tvc.m_cc_overflow, "Number of coins would overflow");
cryptonote::cc_account_data_t ad;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(mint.cc_account, ad), false, "Failed to get item balances");
@ -103,7 +104,6 @@ bool cc_command_handler_mint::execute(cryptonote::BlockchainDB &db, const crypto
ad.balance -= money_needed;
db.set_cc_account_item_balances(mint.cc_account, ad.item_balances);
db.set_cc_account_balance(mint.cc_account, ad.balance);
db.set_cc_custom_item_amount(mint.coin, cid.amount + mint.amount);
CHECK_AND_ASSERT_MES(cc::increase_item_count(db, mint.coin, mint.amount), false, "Item count anomaly");
CHECK_AND_ASSERT_MES(cc::distribute_to_treasuries(db, mint.amount * COIN_MINTING_FEE, false), false, "Failed to distribute to treasuries");
@ -130,7 +130,6 @@ bool cc_command_handler_mint::revert(cryptonote::BlockchainDB &db, const crypton
ad.balance += money_needed;
db.set_cc_account_item_balances(mint.cc_account, ad.item_balances);
db.set_cc_account_balance(mint.cc_account, ad.balance);
db.set_cc_custom_item_amount(mint.coin, cid.amount - mint.amount);
CHECK_AND_ASSERT_MES(cc::decrease_item_count(db, mint.coin, mint.amount), false, "Item count anomaly");
CHECK_AND_ASSERT_MES(cc::distribute_to_treasuries(db, mint.amount * COIN_MINTING_FEE, true), false, "Failed to distribute from treasuries");

View File

@ -107,7 +107,7 @@ bool cc_command_handler_new_item::execute(cryptonote::BlockchainDB &db, const cr
std::vector<uint64_t> user_data(NUM_CUSTOM_ITEM_USER_DATA, 0);
user_data[0] = new_item.group == COINS_ITEM_GROUP ? MAKE_COLLECTIBLE_COIN_EVENT_USER_DATA_0() : 0;
const uint32_t id = db.allocate_new_cc_custom_item(new_item.amount, new_item.cc_account, db.height() - 1, new_item.name, new_item.is_group, new_item.is_public, new_item.group, new_item.primary_description, new_item.secondary_description, user_data);
const uint32_t id = db.allocate_new_cc_custom_item(new_item.cc_account, db.height() - 1, new_item.name, new_item.is_group, new_item.is_public, new_item.group, new_item.primary_description, new_item.secondary_description, user_data);
CHECK_AND_ASSERT_MES(id >= ITEM_FIRST_USER && id <= ITEM_LAST_USER, false, "Item creation failed");
if (new_item.amount > 0)

View File

@ -71,7 +71,8 @@ bool cc_command_handler_smelt::check(const cryptonote::BlockchainDB &db, const c
CHECK_COMMAND_SET(db.get_cc_custom_item_data(smelt.coin, cid), tvc.m_cc_bad_item, "Invalid coin id");
CHECK_COMMAND_SET(!cid.is_group, tvc.m_cc_bad_item, "Invalid coin id");
CHECK_COMMAND_SET(cid.group == COINS_ITEM_GROUP, tvc.m_cc_bad_item, "Invalid coin id");
CHECK_COMMAND_SET(cid.amount >= smelt.amount, tvc.m_cc_overflow, "Amount of coins would underflow");
const uint64_t amount = db.get_cc_item_count(smelt.coin);
CHECK_COMMAND_SET(amount >= smelt.amount, tvc.m_cc_overflow, "Amount of coins would underflow");
cryptonote::cc_account_data_t ad;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(smelt.cc_account, ad), false, "Failed to get item balances");
@ -102,7 +103,6 @@ bool cc_command_handler_smelt::execute(cryptonote::BlockchainDB &db, const crypt
ad.balance += money_returned;
db.set_cc_account_item_balances(smelt.cc_account, ad.item_balances);
db.set_cc_account_balance(smelt.cc_account, ad.balance);
db.set_cc_custom_item_amount(smelt.coin, cid.amount - smelt.amount);
CHECK_AND_ASSERT_MES(cc::decrease_item_count(db, smelt.coin, smelt.amount), false, "Item count anomaly");
CHECK_AND_ASSERT_MES(cc::distribute_to_treasuries(db, smelt.amount * COIN_SMELTING_FEE, false), false, "Failed to distribute to treasuries");
@ -130,7 +130,6 @@ bool cc_command_handler_smelt::revert(cryptonote::BlockchainDB &db, const crypto
ad.balance -= money_returned;
db.set_cc_account_item_balances(smelt.cc_account, ad.item_balances);
db.set_cc_account_balance(smelt.cc_account, ad.balance);
db.set_cc_custom_item_amount(smelt.coin, cid.amount + smelt.amount);
CHECK_AND_ASSERT_MES(cc::increase_item_count(db, smelt.coin, smelt.amount), false, "Item count anomaly");
CHECK_AND_ASSERT_MES(cc::distribute_to_treasuries(db, smelt.amount * COIN_SMELTING_FEE, true), false, "Failed to distribute from treasuries");

View File

@ -19,7 +19,6 @@ struct cc_custom_item_t
uint32_t id;
uint32_t creator;
uint64_t creation_height;
uint32_t amount;
bool is_group;
bool is_public;
uint32_t group;
@ -31,7 +30,7 @@ struct cc_custom_item_t
bool operator==(const cc_custom_item_t &other) const
{
return id == other.id && creator == other.creator && creation_height == other.creation_height && amount == other.amount
return id == other.id && creator == other.creator && creation_height == other.creation_height
&& is_group == other.is_group && is_public == other.is_public && group == other.group && ignore == other.ignore
&& primary_description == other.primary_description && secondary_description == other.secondary_description
&& user_data == other.user_data;

View File

@ -1423,24 +1423,25 @@ static void add_cities(const BlockchainDB &db, cc_command_game_update_t &cg, gam
uint64_t actual_payment = payment;
cryptonote::cc_account_data_t ad;
CHECK_AND_ASSERT_MES(db.get_cc_account_data(cid.creator, ad), false, "Failed to get account data");
const uint64_t amount = db.get_cc_item_count(cid.id);
if (item == 0)
{
CHECK_AND_ASSERT_MES(payment <= std::numeric_limits<uint64_t>::max() / cid.amount, false, "Payment overflow");
if (ad.balance < payment * cid.amount)
CHECK_AND_ASSERT_MES(payment <= std::numeric_limits<uint64_t>::max() / amount, false, "Payment overflow");
if (ad.balance < payment * amount)
{
MDEBUG("Not enough balance to meet mortgage terms, defaulting");
actual_payment = ad.balance / cid.amount;
actual_payment = ad.balance / amount;
}
}
else
{
CHECK_AND_ASSERT_MES(payment <= std::numeric_limits<uint32_t>::max() / cid.amount, false, "Payment overflow");
CHECK_AND_ASSERT_MES(payment <= std::numeric_limits<uint32_t>::max() / amount, false, "Payment overflow");
const auto i = ad.item_balances.find(item);
const uint32_t item_balance = i == ad.item_balances.end() ? 0 : i->second;
if (item_balance < payment * cid.amount)
if (item_balance < payment * amount)
{
MDEBUG("Not enough item balance to meet mortgage terms, defaulting");
actual_payment = item_balance / cid.amount;
actual_payment = item_balance / amount;
}
}

View File

@ -340,7 +340,7 @@ public:
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve);
bool get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t &balance, std::map<uint32_t, uint32_t> &items);
bool get_cc_custom_item_data(uint32_t id, std::string &name);
bool get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint32_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data);
bool get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data);
bool get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc::cc_badge_data_t> &data);
bool get_cc_badge_totals(std::vector<std::pair<uint32_t, std::vector<uint32_t>>> &badges);
bool get_last_update_events(uint64_t &block_height, uint64_t &timestamp, cc::game_events_t &events);
@ -362,7 +362,7 @@ public:
bool get_cc_order_book(std::vector<cryptonote::matchable_order_as_string_t> *bids, std::vector<cryptonote::matchable_order_as_string_t> *offers, const std::vector<uint32_t> &type, const std::vector<uint32_t> &id);
bool get_cc_discoveries(std::vector<cryptonote::discovery_t> &discoveries);
bool get_cc_cities(std::vector<cryptonote::city_t> &cities);
bool get_cc_custom_items(std::vector<cc::cc_custom_item_t> &items);
bool get_cc_custom_items(std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items);
bool get_cc_accounts(std::vector<std::tuple<uint32_t, std::string, bool>> &accounts);
bool get_cc_flags(std::vector<std::tuple<uint32_t, std::string, bool>> &accounts);
bool get_cc_flag_owner(uint32_t id, uint32_t &owner);
@ -1034,11 +1034,11 @@ bool GameWalletInternal::get_cc_cities(std::vector<cryptonote::city_t> &cities)
return w->get_cc_cities(cities);
}
bool GameWalletInternal::get_cc_custom_items(std::vector<cc::cc_custom_item_t> &items)
bool GameWalletInternal::get_cc_custom_items(std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items)
{
if (!w->get_cc_custom_items({}, items))
return false;
std::sort(items.begin(), items.end(), [](const cc::cc_custom_item_t &item0, const cc::cc_custom_item_t &item1) { return item0.id < item1.id; });
std::sort(items.begin(), items.end(), [](const std::pair<cc::cc_custom_item_t, uint64_t> &item0, const std::pair<cc::cc_custom_item_t, uint64_t> &item1) { return item0.first.id < item1.first.id; });
return true;
}
@ -1153,34 +1153,34 @@ bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &name)
return true;
}
bool GameWalletInternal::get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint32_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data)
bool GameWalletInternal::get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data)
{
std::vector<cc::cc_custom_item_t> cid;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> cid;
if (!w->get_cc_custom_items({id}, cid))
return false;
if (cid.size() != 1 || cid[0].id != id)
if (cid.size() != 1 || cid[0].first.id != id)
return false;
creator = cid[0].creator;
amount = cid[0].amount;
name = std::move(cid[0].name);
primary_description = std::move(cid[0].primary_description);
secondary_description = std::move(cid[0].secondary_description);
ignore = cid[0].ignore;
is_group = cid[0].is_group;
is_public = cid[0].is_public;
group = cid[0].group;
user_data = std::move(cid[0].user_data);
creator = cid[0].first.creator;
amount = cid[0].second;
name = std::move(cid[0].first.name);
primary_description = std::move(cid[0].first.primary_description);
secondary_description = std::move(cid[0].first.secondary_description);
ignore = cid[0].first.ignore;
is_group = cid[0].first.is_group;
is_public = cid[0].first.is_public;
group = cid[0].first.group;
user_data = std::move(cid[0].first.user_data);
return true;
}
bool GameWalletInternal::get_cc_custom_item_data(uint32_t id, std::string &name)
{
std::vector<cc::cc_custom_item_t> cid;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> cid;
if (!w->get_cc_custom_items({id}, cid))
return false;
if (cid.size() != 1 || cid[0].id != id)
if (cid.size() != 1 || cid[0].first.id != id)
return false;
name = std::move(cid[0].name);
name = std::move(cid[0].first.name);
return true;
}
@ -1696,7 +1696,7 @@ bool GameWallet::get_cc_cities(std::vector<cryptonote::city_t> &cities)
return internal->get_cc_cities(cities);
}
bool GameWallet::get_cc_custom_items(std::vector<cc::cc_custom_item_t> &items)
bool GameWallet::get_cc_custom_items(std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items)
{
return internal->get_cc_custom_items(items);
}
@ -1812,7 +1812,7 @@ bool GameWallet::get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t
return internal->get_cc_account_reserve(id, account, balance, items);
}
bool GameWallet::get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint32_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data)
bool GameWallet::get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data)
{
return internal->get_cc_custom_item_data(id, creator, amount, name, is_group, is_public, group, primary_description, secondary_description, ignore, user_data);
}

View File

@ -61,7 +61,7 @@ public:
bool get_cc_account_data(uint32_t id, std::string &public_key, uint64_t &balance, std::map<uint32_t, uint32_t> &item_balances, std::vector<uint32_t> &flags, std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges, std::map<uint32_t, uint32_t> &attributes, std::string &name, std::string &description, bool &ignore, uint32_t &inviting_account, uint32_t &num_invited, uint32_t &first_flag, uint32_t &script, uint32_t &script_state, uint32_t &script_city, std::map<uint32_t, std::pair<uint64_t, std::map<uint32_t, uint32_t>>> &reserve);
bool get_cc_account_reserve(uint32_t id, uint32_t account, uint64_t &balance, std::map<uint32_t, uint32_t> &items);
bool get_cc_custom_item_data(uint32_t id, std::string &name);
bool get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint32_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data);
bool get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint64_t &amount, std::string &name, bool &is_group, bool &is_public, uint32_t &group, std::string &primary_description, std::string &secondary_description, bool &ignore, std::vector<uint64_t> &user_data);
bool get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc::cc_badge_data_t> &data);
bool get_cc_badge_totals(std::vector<std::pair<uint32_t, std::vector<uint32_t>>> &badges);
bool get_last_update_events(uint64_t &block_height, uint64_t &timestamp, cc::game_events_t &events);
@ -74,7 +74,7 @@ public:
bool get_cc_order_book(std::vector<cryptonote::matchable_order_as_string_t> *bids, std::vector<cryptonote::matchable_order_as_string_t> *offers, const std::vector<uint32_t> &type, const std::vector<uint32_t> &id);
bool get_cc_discoveries(std::vector<cryptonote::discovery_t> &discoveries);
bool get_cc_cities(std::vector<cryptonote::city_t> &cities);
bool get_cc_custom_items(std::vector<cc::cc_custom_item_t> &items);
bool get_cc_custom_items(std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items);
bool get_cc_accounts(std::vector<std::tuple<uint32_t, std::string, bool>> &accounts);
bool get_cc_flags(std::vector<std::tuple<uint32_t, std::string, bool>> &flags);
bool get_cc_flag(uint32_t flag, cryptonote::cc_snapshot::flag_state_t &fd);

View File

@ -6098,7 +6098,8 @@ void CryptoCityUrho3D::HandleRequestItemData(StringHash eventType, VariantMap& e
if (wallet)
{
const uint32_t id = eventData[RequestItemData::P_ID].GetUInt();
uint32_t creator, amount, group;
uint32_t creator, group;
uint64_t amount;
std::string name;
bool ignore, is_group, is_public;
std::string primary_description, secondary_description;
@ -6107,7 +6108,7 @@ void CryptoCityUrho3D::HandleRequestItemData(StringHash eventType, VariantMap& e
{
gameState.set_item_name(id, name, ignore);
eventData[RequestItemData::P_AMOUNT] = amount;
eventData[RequestItemData::P_AMOUNT] = (unsigned long long)amount;
eventData[RequestItemData::P_CREATOR] = creator;
eventData[RequestItemData::P_NAME] = gameState.get_item_name(id).c_str();
eventData[RequestItemData::P_PRIMARY_DESCRIPTION] = primary_description.c_str();

View File

@ -51,7 +51,7 @@ UIDividendDialog::~UIDividendDialog()
void UIDividendDialog::FillSources(const GameState *game, const std::shared_ptr<GameWallet> &w)
{
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
if (w)
{
w->get_cc_custom_items(items);
@ -68,8 +68,9 @@ void UIDividendDialog::FillSources(const GameState *game, const std::shared_ptr<
owned_item_builder.AddItem(new ItemItem(game->get_item_name(item).c_str(), item));
distributed_item_builder.AddItem(new ItemItem(game->get_item_name(item).c_str(), item));
}
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < NUM_PREDEFINED_ITEMS || item.id >= NUM_ITEMS)
continue;
if (item.is_group)

View File

@ -140,14 +140,14 @@ void UIIgnoreDialog::FillSources(const std::shared_ptr<GameWallet> &w)
}
}
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
if (w->get_cc_custom_items(items))
{
for (const auto &e: items)
{
const bool ignored = std::find(ignore.items.begin(), ignore.items.end(), e.id) != ignore.items.end();
TBGenericStringItem *item = new TBGenericStringItem(e.name);
item->tag.SetInt(e.id);
const bool ignored = std::find(ignore.items.begin(), ignore.items.end(), e.first.id) != ignore.items.end();
TBGenericStringItem *item = new TBGenericStringItem(e.first.name);
item->tag.SetInt(e.first.id);
(ignored ? items_ignore_builder : items_unignore_builder).AddItem(item);
}
}

View File

@ -37,18 +37,18 @@ UIMintDialog::CoinWidget::CoinWidget(UIMintDialog::CoinItem *item, CoinSource *s
g_widgets_reader->LoadFile(GetContentRoot(), "cc/mint-row.tb.txt");
const cc::cc_custom_item_t &c = item->coin;
const cc::cc_custom_item_t &c = item->coin.first;
TBTextField *nameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("name"));
nameWidget->SetText(c.name.c_str());
TBTextField *ownedWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("owned"));
auto it = item->dialog->game->playerState.item_balances.find(item->coin.id);
auto it = item->dialog->game->playerState.item_balances.find(c.id);
const uint32_t owned = it == item->dialog->game->playerState.item_balances.end() ? 0 : it->second;
ownedWidget->SetText(std::to_string(owned).c_str());
TBTextField *totalWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("total"));
totalWidget->SetText(std::to_string(c.amount).c_str());
totalWidget->SetText(std::to_string(item->coin.second).c_str());
TBTextField *deadlineWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("deadline"));
const uint64_t last_block = c.creation_height + COIN_MINTING_WINDOW;
@ -74,7 +74,7 @@ UIMintDialog::CoinWidget::CoinWidget(UIMintDialog::CoinItem *item, CoinSource *s
bool UIMintDialog::CoinWidget::OnEvent(const tb::TBWidgetEvent &ev)
{
const UIMintDialog::CoinItem *item = m_source->GetItem(m_index);
const cc::cc_custom_item_t &c = item->coin;
const cc::cc_custom_item_t &c = item->coin.first;
if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("mint"))
{
@ -146,7 +146,7 @@ void UIMintDialog::FilterCoins()
const size_t n_elements = items.size();
for (unsigned int n = 0; n < n_elements; ++n)
{
const cc::cc_custom_item_t &item = items[n];
const cc::cc_custom_item_t &item = items[n].first;
if (item.is_group)
continue;
if (item.group != COINS_ITEM_GROUP)
@ -157,7 +157,7 @@ void UIMintDialog::FilterCoins()
if (game->top_height > last_block)
continue;
}
builder.AddItem(new CoinItem(this, item));
builder.AddItem(new CoinItem(this, items[n]));
}
}

View File

@ -59,15 +59,15 @@ private:
tb::TBTextField *mintingFeeWidget;
tb::TBCheckBox *showAllWidget;
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
std::string last_refresh_stop_hash;
class CoinItem: public tb::TBGenericStringItem
{
public:
CoinItem(UIMintDialog *dialog, const cc::cc_custom_item_t &coin): TBGenericStringItem(coin.name.c_str()), dialog(dialog), coin(coin) {}
CoinItem(UIMintDialog *dialog, const std::pair<cc::cc_custom_item_t, uint64_t> &coin): TBGenericStringItem(coin.first.name.c_str()), dialog(dialog), coin(coin) {}
UIMintDialog *dialog;
cc::cc_custom_item_t coin;
std::pair<cc::cc_custom_item_t, uint64_t> coin;
bool operator==(const CoinItem &other) const { return coin == other.coin; }
};

View File

@ -50,7 +50,7 @@ UINewItemDialog::~UINewItemDialog()
void UINewItemDialog::FillGroups(const GameState *game, const std::shared_ptr<GameWallet> &w)
{
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
if (w)
{
w->get_cc_custom_items(items);
@ -59,8 +59,9 @@ void UINewItemDialog::FillGroups(const GameState *game, const std::shared_ptr<Ga
CachingSourceBuilder<ItemItem> item_builder(item_source);
item_builder.AddItem(new ItemItem("None", 0));
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < ITEM_FIRST_USER || item.id > ITEM_LAST_USER)
continue;
if (!item.is_group)

View File

@ -11,6 +11,7 @@
#include "cc/cc_config.h"
#include "cc/cc.h"
#include "cc/cc_custom_item.h"
#include "cc/cc_mortgage.h"
#include "game-state.h"
#include "game-wallet.h"
#include "UTBRendererBatcher.h"
@ -54,7 +55,7 @@ UINewMortgageDialog::~UINewMortgageDialog()
void UINewMortgageDialog::FillSources(const GameState *game, const std::shared_ptr<GameWallet> &w)
{
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
if (w)
{
w->get_cc_custom_items(items);
@ -69,13 +70,17 @@ void UINewMortgageDialog::FillSources(const GameState *game, const std::shared_p
continue;
distributed_item_builder.AddItem(new ItemItem(game->get_item_name(item).c_str(), item));
}
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < NUM_PREDEFINED_ITEMS || item.id >= NUM_ITEMS)
continue;
if (item.is_group)
continue;
if (item.amount == 0)
uint32_t mortgage_flag, mortgage_item;
uint64_t tick_payment, maturity_payment, maturity_height;
cc::get_mortgage_data(item.user_data, mortgage_flag, mortgage_item, tick_payment, maturity_payment, maturity_height);
if (maturity_height && maturity_height <= game->top_height)
continue;
distributed_item_builder.AddItem(new ItemItem(item.name.c_str(), item.id));
}

View File

@ -36,18 +36,18 @@ UISmeltDialog::CoinWidget::CoinWidget(UISmeltDialog::CoinItem *item, CoinSource
g_widgets_reader->LoadFile(GetContentRoot(), "cc/smelt-row.tb.txt");
const cc::cc_custom_item_t &c = item->coin;
const cc::cc_custom_item_t &c = item->coin.first;
TBTextField *nameWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("name"));
nameWidget->SetText(c.name.c_str());
TBTextField *ownedWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("owned"));
auto it = item->dialog->game->playerState.item_balances.find(item->coin.id);
auto it = item->dialog->game->playerState.item_balances.find(c.id);
const uint32_t owned = it == item->dialog->game->playerState.item_balances.end() ? 0 : it->second;
ownedWidget->SetText(std::to_string(owned).c_str());
TBTextField *totalWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("total"));
totalWidget->SetText(std::to_string(c.amount).c_str());
totalWidget->SetText(std::to_string(item->coin.second).c_str());
TBTextField *descWidget = GetWidgetByIDAndType<TBTextField>(TBIDC("desc"));
descWidget->SetText(c.primary_description.c_str());
@ -60,7 +60,7 @@ UISmeltDialog::CoinWidget::CoinWidget(UISmeltDialog::CoinItem *item, CoinSource
bool UISmeltDialog::CoinWidget::OnEvent(const tb::TBWidgetEvent &ev)
{
const UISmeltDialog::CoinItem *item = m_source->GetItem(m_index);
const cc::cc_custom_item_t &c = item->coin;
const cc::cc_custom_item_t &c = item->coin.first;
if (ev.type == EVENT_TYPE_CLICK && ev.target->GetID() == TBIDC("smelt"))
{
@ -79,7 +79,7 @@ bool UISmeltDialog::CoinWidget::OnEvent(const tb::TBWidgetEvent &ev)
new MessageBox(item->dialog->context_, "Invalid amount");
return true;
}
auto it = item->dialog->game->playerState.item_balances.find(item->coin.id);
auto it = item->dialog->game->playerState.item_balances.find(c.id);
const uint32_t owned = it == item->dialog->game->playerState.item_balances.end() ? 0 : it->second;
if (amount > owned)
{
@ -128,11 +128,11 @@ void UISmeltDialog::RegisterObject(Context* context)
void UISmeltDialog::FilterCoins()
{
CachingSourceBuilder<CoinItem> builder(coinSource);
const size_t n_elements = items.size();
CachingSourceBuilder<CoinItem> builder(coinSource);
for (unsigned int n = 0; n < n_elements; ++n)
{
const cc::cc_custom_item_t &item = items[n];
const cc::cc_custom_item_t &item = items[n].first;
if (item.is_group)
continue;
if (item.group != COINS_ITEM_GROUP)
@ -140,7 +140,7 @@ void UISmeltDialog::FilterCoins()
const auto it = game->playerState.item_balances.find(item.id);
if (it == game->playerState.item_balances.end() || it->second == 0)
continue;
builder.AddItem(new CoinItem(this, item));
builder.AddItem(new CoinItem(this, items[n]));
}
}

View File

@ -58,15 +58,15 @@ private:
tb::TBSelectList *coinListWidget;
tb::TBTextField *smeltingFeeWidget;
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
std::string last_refresh_stop_hash;
class CoinItem: public tb::TBGenericStringItem
{
public:
CoinItem(UISmeltDialog *dialog, const cc::cc_custom_item_t &coin): TBGenericStringItem(coin.name.c_str()), dialog(dialog), coin(coin) {}
CoinItem(UISmeltDialog *dialog, const std::pair<cc::cc_custom_item_t, uint64_t> &coin): TBGenericStringItem(coin.first.name.c_str()), dialog(dialog), coin(coin) {}
UISmeltDialog *dialog;
cc::cc_custom_item_t coin;
std::pair<cc::cc_custom_item_t, uint64_t> coin;
bool operator==(const CoinItem &other) const { return coin == other.coin; }
};

View File

@ -304,8 +304,9 @@ void UITradeDialog::UpdateItemList(const std::shared_ptr<GameWallet> &w)
if (filters[FILTER_COINS]->GetValue())
#endif
{
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < ITEM_FIRST_USER || item.id > ITEM_LAST_USER)
continue;
if (item.is_group)
@ -322,15 +323,19 @@ void UITradeDialog::UpdateItemList(const std::shared_ptr<GameWallet> &w)
if (filters[FILTER_MORTGAGES]->GetValue())
#endif
{
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < ITEM_FIRST_USER || item.id > ITEM_LAST_USER)
continue;
if (item.is_group)
continue;
if (item.group != MORTGAGE_ITEM_GROUP)
continue;
if (item.amount == 0) // matured mortgage items are destroyed, but the template stays
uint32_t mortgage_flag, mortgage_item;
uint64_t tick_payment, maturity_payment, maturity_height;
cc::get_mortgage_data(item.user_data, mortgage_flag, mortgage_item, tick_payment, maturity_payment, maturity_height);
if (maturity_height && maturity_height <= game->top_height)
continue;
if (!MatchesActivity(cryptonote::cc_command_trade_t::type_item, item.id))
continue;
@ -342,8 +347,9 @@ void UITradeDialog::UpdateItemList(const std::shared_ptr<GameWallet> &w)
if (filters[FILTER_CUSTOM]->GetValue())
#endif
{
for (const auto &item: items)
for (const auto &e: items)
{
const auto &item = e.first;
if (item.id < ITEM_FIRST_USER || item.id > ITEM_LAST_USER)
continue;
if (item.is_group)
@ -500,7 +506,8 @@ std::string UITradeDialog::GetMarketDetails(const std::shared_ptr<GameWallet> &w
ss << "Type: food\n";
else if (id >= ITEM_FIRST_USER && id <= ITEM_LAST_USER)
{
uint32_t creator, amount, group;
uint32_t creator, group;
uint64_t amount;
std::string name, primary_description, secondary_description;
bool ignore, is_group, is_public;
std::vector<uint64_t> user_data;
@ -564,11 +571,12 @@ std::string UITradeDialog::GetMarketDetails(const std::shared_ptr<GameWallet> &w
{
if (group)
{
uint32_t creator_group, amount_group, group_group;
uint32_t creator_group, group_group;
uint64_t creator_amount;
std::string name_group, primary_description_group, secondary_description_group;
bool ignore_group, is_group_group, is_public_group;
std::vector<uint64_t> user_data_group;
if (w->get_cc_custom_item_data(group, creator_group, amount_group, name_group, is_group_group, is_public_group, group_group, primary_description_group, secondary_description_group, ignore_group, user_data_group))
if (w->get_cc_custom_item_data(group, creator_group, creator_amount, name_group, is_group_group, is_public_group, group_group, primary_description_group, secondary_description_group, ignore_group, user_data_group))
ss << "Group: " << name_group << "\n";
else
ss << "Group: " << group << "\n";

View File

@ -218,7 +218,7 @@ private:
std::string last_refresh_stop_hash;
bool refresh;
Activity activity;
std::vector<cc::cc_custom_item_t> items;
std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> items;
std::vector<cryptonote::matchable_order_as_string_t> all_bids, all_offers;
bool update_item_list;
std::vector<std::pair<std::string, uint64_t>> cancelled_nonces;

View File

@ -4457,9 +4457,11 @@ namespace cryptonote
if (req.ids.empty())
{
db.for_all_cc_custom_items([&res](const cc::cc_custom_item_t &cid) {
res.items.push_back({cid.id, cid.creator, cid.creation_height, cid.amount, cid.is_group, cid.is_public, cid.group, cid.ignore, cid.name, cid.primary_description, cid.secondary_description, cid.user_data});
res.items.push_back({cid.id, cid.creator, cid.creation_height, 0, cid.is_group, cid.is_public, cid.group, cid.ignore, cid.name, cid.primary_description, cid.secondary_description, cid.user_data});
return true;
});
for (auto &e: res.items)
e.amount = db.get_cc_item_count(e.id);
}
else
{
@ -4472,7 +4474,8 @@ namespace cryptonote
error_resp.message = "Error retrieving item data";
return false;
}
res.items.push_back({cid.id, cid.creator, cid.creation_height, cid.amount, cid.is_group, cid.is_public, cid.group, cid.ignore, cid.name, cid.primary_description, cid.secondary_description, std::move(cid.user_data)});
const uint64_t amount = db.get_cc_item_count(id);
res.items.push_back({cid.id, cid.creator, cid.creation_height, amount, cid.is_group, cid.is_public, cid.group, cid.ignore, cid.name, cid.primary_description, cid.secondary_description, std::move(cid.user_data)});
}
}
}

View File

@ -3604,7 +3604,7 @@ namespace cryptonote
uint32_t id;
uint32_t creator;
uint64_t creation_height;
uint32_t amount;
uint64_t amount;
bool is_group;
bool is_public;
uint32_t group;

View File

@ -953,7 +953,7 @@ private:
bool get_cc_flag_data(uint32_t id, uint32_t &owner, uint32_t &city, uint8_t &role, uint32_t &x0, uint32_t &y0, uint32_t &x1, uint32_t &y1, uint32_t &repair, uint32_t &economic_power, uint32_t &influence, uint64_t &construction_height, std::map<uint32_t, uint32_t> &budget, std::vector<uint16_t> &palette, uint8_t &fire_state, bool &active, std::string &name, bool &ignore, uint64_t &last_firefighting_height, uint64_t &service_price, uint32_t &elevation_bonus, uint8_t &crop, uint64_t &sow_height, uint8_t &vegetables_nutrients, uint8_t &grain_nutrients, uint32_t &mortgage);
bool get_cc_discoveries(std::vector<cryptonote::discovery_t> &discoveries);
bool get_cc_cities(std::vector<cryptonote::city_t> &cities);
bool get_cc_custom_items(const std::vector<uint32_t> &ids, std::vector<cc::cc_custom_item_t> &items);
bool get_cc_custom_items(const std::vector<uint32_t> &ids, std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items);
bool get_cc_accounts(std::vector<std::tuple<uint32_t, std::string, bool>> &accounts);
bool get_cc_flags(std::vector<std::tuple<uint32_t, std::string, bool>> &flags);
bool get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc::cc_badge_data_t> &data);

View File

@ -458,7 +458,7 @@ bool wallet2::get_cc_cities(std::vector<cryptonote::city_t> &cities)
return true;
}
bool wallet2::get_cc_custom_items(const std::vector<uint32_t> &ids, std::vector<cc::cc_custom_item_t> &items)
bool wallet2::get_cc_custom_items(const std::vector<uint32_t> &ids, std::vector<std::pair<cc::cc_custom_item_t, uint64_t>> &items)
{
cryptonote::COMMAND_RPC_CC_GET_CUSTOM_ITEMS::request req = AUTO_VAL_INIT(req);
cryptonote::COMMAND_RPC_CC_GET_CUSTOM_ITEMS::response res = AUTO_VAL_INIT(res);
@ -477,7 +477,7 @@ bool wallet2::get_cc_custom_items(const std::vector<uint32_t> &ids, std::vector<
{
if (e.user_data.size() != NUM_CUSTOM_ITEM_USER_DATA)
return false;
items.push_back({e.id, e.creator, e.creation_height, e.amount, e.is_group, e.is_public, e.group, e.ignore, std::move(e.name), std::move(e.pdesc), std::move(e.sdesc), std::move(e.user_data)});
items.push_back(std::make_pair(cc::cc_custom_item_t{e.id, e.creator, e.creation_height, e.is_group, e.is_public, e.group, e.ignore, std::move(e.name), std::move(e.pdesc), std::move(e.sdesc), std::move(e.user_data)}, e.amount));
}
return true;
}

View File

@ -103,7 +103,7 @@ public:
virtual void set_hard_fork_version(uint64_t height, uint8_t version) override { if (height >= hf.size()) hf.resize(height + 1); hf[height] = version; }
virtual uint8_t get_hard_fork_version(uint64_t height) const override { if (height >= hf.size()) return 255; return hf[height]; }
virtual uint32_t allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data) { return item_id++; }
virtual uint32_t allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, uint64_t user_data) { return item_id++; }
virtual bool get_cc_city_data(uint32_t id, cryptonote::cc_city_data_t &cd) const { cd = {}; return true; }

View File

@ -200,6 +200,7 @@ class CCTest():
self.reset_and_check_states()
state1 = self.get_state()
assert state0 == state1, self.get_diff(state0, state1)
self.check_no_items()
def reset(self):
print('Resetting blockchain')
@ -308,8 +309,8 @@ class CCTest():
def check_no_items(self):
daemon = self.daemon
print('Checking there are no items at game start')
res = daemon.cc_get_item_count([x for x in range(NUM_PREDEFINED_ITEMS)])
print('Checking there are no items')
res = daemon.cc_get_item_count([x for x in range(NUM_PREDEFINED_ITEMS)] + [x + ITEM_FIRST_USER for x in range(256)])
if 'count' in res:
for x in res.count:
assert x == 0
@ -905,6 +906,9 @@ class CCTest():
assert custom_item.pdesc == "test"
expected_item_balances[2] = self.add_item(expected_item_balances[2], custom_item_id, 100)
res = daemon.cc_get_item_count([custom_item_id])
assert res.counts == [100], res
res = daemon.cc_get_flag(flag_id)
assert res.mortgage == custom_item_id
@ -923,6 +927,9 @@ class CCTest():
expected_item_balances[2] = self.add_item(expected_item_balances[2], custom_item_id, -25)
expected_item_balances[1] = self.add_item(expected_item_balances[1], custom_item_id, 25)
res = daemon.cc_get_item_count([x for x in range(NUM_PREDEFINED_ITEMS)])
assert res.counts == item_counts
# pass an update - tick
res = daemon.get_info()
height = res.height
@ -946,6 +953,9 @@ class CCTest():
expected_item_balances[2] = self.add_item(expected_item_balances[2], ITEM_LABOUR, -25 * 10)
expected_item_balances[1] = self.add_item(expected_item_balances[1], ITEM_LABOUR, 25 * 10)
expected_item_balances[2] = self.add_item(expected_item_balances[2], custom_item_id, -75)
expected_item_balances[1] = self.add_item(expected_item_balances[1], custom_item_id, -25)
# check item balances (gold/wood balances are unknown past the update)
for i in range(4):
res = daemon.cc_get_account(account_id[i])
@ -965,7 +975,8 @@ class CCTest():
res = daemon.cc_get_flag(flag_id)
assert res.mortgage == 0
print("TODO: ite mshould be destroyed after that ?")
res = daemon.cc_get_item_count([custom_item_id])
assert res.counts == [0], res
def test_trading(self):
daemon = self.daemon

View File

@ -148,7 +148,6 @@ private:
struct custom_item_t
{
bool in_use;
uint32_t amount;
uint32_t creator;
uint64_t creation_height;
std::string name;
@ -159,7 +158,7 @@ private:
std::string sdesc;
std::vector<uint64_t> user_data;
bool operator==(const custom_item_t &other) const { return amount == other.amount && name == other.name && creator == other.creator && creation_height == other.creation_height && is_group == other.is_group && group == other.group && pdesc == other.pdesc && sdesc == other.sdesc && ignore == other.ignore && user_data == other.user_data; }
bool operator==(const custom_item_t &other) const { return name == other.name && creator == other.creator && creation_height == other.creation_height && is_group == other.is_group && group == other.group && pdesc == other.pdesc && sdesc == other.sdesc && ignore == other.ignore && user_data == other.user_data; }
};
static crypto::public_key DEAD_PKEY;
@ -758,12 +757,12 @@ public:
sed.push_back({e.event, e.start_height, e.duration});
}
uint32_t allocate_new_cc_custom_item(uint32_t amount, uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data)
uint32_t allocate_new_cc_custom_item(uint32_t creator, uint64_t creation_height, const std::string &name, bool is_group, bool is_public, uint32_t group, const std::string &primary_description, const std::string &secondary_description, const std::vector<uint64_t> &user_data)
{
uint32_t actual_id;
state.items.push_back({});
actual_id = state.items.size() - 1;
state.items[actual_id] = {true, amount, creator, creation_height, name, false, is_group, group, primary_description, secondary_description, user_data};
state.items[actual_id] = {true, creator, creation_height, name, false, is_group, group, primary_description, secondary_description, user_data};
return actual_id + ITEM_FIRST_USER;
}
@ -777,7 +776,6 @@ public:
if (!state.items[id].in_use)
return false;
cid.id = id;
cid.amount = state.items[id].amount;
cid.name = state.items[id].name;
cid.is_group = state.items[id].is_group;
cid.group = state.items[id].group;
@ -794,13 +792,6 @@ public:
state.items[id].ignore = ignore;
}
void set_cc_custom_item_amount(uint32_t id, uint32_t amount)
{
if (!state.items[id].in_use)
return;
state.items[id].amount = amount;
}
bool for_all_cc_custom_items(std::function<bool(const cc::cc_custom_item_t &cid)> f) const
{
for (size_t i = 0; i < state.items.size(); ++i)
@ -810,7 +801,6 @@ public:
continue;
cc::cc_custom_item_t cid{};
cid.id = i;
cid.amount = item.amount;
cid.name = item.name;
cid.is_group = item.is_group;
cid.group = item.group;