forked from townforge/townforge
add a new command to destroy owned items
This commit is contained in:
parent
31c0293151
commit
3891353d7e
@ -34,6 +34,7 @@ TBLayout: axis: y, distribution-position: "left top", distribution: "available"
|
||||
TBButton: skin: "TBButton.column", text: "Research", id: "actions-research"
|
||||
TBButton: skin: "TBButton.column", text: "New item" id: "actions-new-item"
|
||||
TBButton: skin: "TBButton.column", text: "Dividend" id: "actions-dividend"
|
||||
TBButton: skin: "TBButton.column", text: "Destroy items", id: "actions-destroy-items"
|
||||
TBButton: skin: "TBButton.column", text: "Ignore" id: "actions-ignore"
|
||||
TBButton: skin: "TBButton.column", text: "Leaderboards" id: "actions-leaderboards"
|
||||
TBButton: skin: "TBButton.column", text: "Chat", id: "actions-chat"
|
||||
|
@ -1927,6 +1927,7 @@ public:
|
||||
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;
|
||||
|
@ -7155,6 +7155,33 @@ 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__);
|
||||
|
@ -548,6 +548,7 @@ private:
|
||||
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);
|
||||
|
@ -243,6 +243,7 @@ public:
|
||||
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; }
|
||||
|
@ -35,6 +35,7 @@ set(cc_sources
|
||||
cc_command_handler_chat.cpp
|
||||
cc_command_handler_create_account.cpp
|
||||
cc_command_handler_demolish.cpp
|
||||
cc_command_handler_destroy_items.cpp
|
||||
cc_command_handler_dividend.cpp
|
||||
cc_command_handler_event_badge.cpp
|
||||
cc_command_handler_found_city.cpp
|
||||
@ -72,6 +73,7 @@ set(cc_headers
|
||||
cc_command_handler_chat.h
|
||||
cc_command_handler_create_account.h
|
||||
cc_command_handler_demolish.h
|
||||
cc_command_handler_destroy_items.h
|
||||
cc_command_handler_dividend.h
|
||||
cc_command_handler_event_badge.h
|
||||
cc_command_handler_found_city.h
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "cc_command_handler_chat.h"
|
||||
#include "cc_command_handler_create_account.h"
|
||||
#include "cc_command_handler_demolish.h"
|
||||
#include "cc_command_handler_destroy_items.h"
|
||||
#include "cc_command_handler_dividend.h"
|
||||
#include "cc_command_handler_found_city.h"
|
||||
#include "cc_command_handler_game_update.h"
|
||||
@ -1705,6 +1706,7 @@ static cc_command_handler &get_cc_command(const cryptonote::cc_command_t &cmd)
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_chat_t &cmd) const { return cc_command_handler_chat::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_create_account_t &cmd) const { return cc_command_handler_create_account::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_demolish_t &cmd) const { return cc_command_handler_demolish::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_destroy_items_t &cmd) const { return cc_command_handler_destroy_items::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_dividend_t &cmd) const { return cc_command_handler_dividend::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_event_badge_t &cmd) const { return cc_command_handler_event_badge::instance; }
|
||||
cc_command_handler &operator()(const cryptonote::cc_command_found_city_t &cmd) const { return cc_command_handler_found_city::instance; }
|
||||
|
116
src/cc/cc_command_handler_destroy_items.cpp
Normal file
116
src/cc/cc_command_handler_destroy_items.cpp
Normal file
@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2019, Crypto City
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "cc/cc.h"
|
||||
#include "cc/cc_custom_item.h"
|
||||
#include "cc_command_handler_destroy_items.h"
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
cc_command_handler_destroy_items cc_command_handler_destroy_items::instance;
|
||||
|
||||
void cc_command_handler_destroy_items::get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const
|
||||
{
|
||||
cc_in = 0;
|
||||
cc_out = 0;
|
||||
}
|
||||
|
||||
uint64_t cc_command_handler_destroy_items::get_cost(const cryptonote::cc_command_t &cmd) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool cc_command_handler_destroy_items::check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, cryptonote::tx_verification_context &tvc) const
|
||||
{
|
||||
const cryptonote::cc_command_destroy_items_t &destroy_items = boost::get<cryptonote::cc_command_destroy_items_t>(cmd);
|
||||
const uint64_t blockchain_height = db.height();
|
||||
|
||||
CHECK_COMMAND_SET(destroy_items.item_id != 0 && destroy_items.item_id < NUM_ITEMS, tvc.m_cc_bad_item, "destroy_items refers to invalid item type");
|
||||
CHECK_COMMAND_SET(cc::is_item_enabled(destroy_items.item_id, blockchain_height), tvc.m_cc_bad_item, "destroy_items refers to disabled item type");
|
||||
CHECK_COMMAND_SET(destroy_items.amount > 0, tvc.m_cc_bad_amount, "destroy_items refers to 0 amount");
|
||||
|
||||
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(item_balances[destroy_items.item_id] >= destroy_items.amount, tvc.m_cc_balance, "Destroying more items of type " << destroy_items.item_id << " than owned");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cc_command_handler_destroy_items::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
|
||||
{
|
||||
const cryptonote::cc_command_destroy_items_t &destroy_items = boost::get<cryptonote::cc_command_destroy_items_t>(cmd);
|
||||
|
||||
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");
|
||||
CHECK_AND_ASSERT_MES(item_balances[destroy_items.item_id] >= destroy_items.amount, false, "Destroying more items of type " << destroy_items.item_id << " than owned");
|
||||
item_balances[destroy_items.item_id] -= destroy_items.amount;
|
||||
db.set_cc_account_item_balances(destroy_items.cc_account, 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_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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cc_command_handler_destroy_items::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
|
||||
{
|
||||
const cryptonote::cc_command_destroy_items_t &destroy_items = boost::get<cryptonote::cc_command_destroy_items_t>(cmd);
|
||||
|
||||
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");
|
||||
CHECK_AND_ASSERT_MES(item_balances[destroy_items.item_id] <= std::numeric_limits<uint32_t>::max() - destroy_items.amount, false, "Item balance would overflow");
|
||||
item_balances[destroy_items.item_id] += destroy_items.amount;
|
||||
db.set_cc_account_item_balances(destroy_items.cc_account, 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_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);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
48
src/cc/cc_command_handler_destroy_items.h
Normal file
48
src/cc/cc_command_handler_destroy_items.h
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright (c) 2019, Crypto City
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cc_command_handler.h"
|
||||
|
||||
namespace cc
|
||||
{
|
||||
|
||||
class cc_command_handler_destroy_items: public cc_command_handler
|
||||
{
|
||||
public:
|
||||
virtual void get_in_out(const cryptonote::cc_command_t &cmd, uint64_t &cc_in, uint64_t &cc_out) const;
|
||||
virtual uint64_t get_cost(const cryptonote::cc_command_t &cmd) const;
|
||||
virtual bool check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, cryptonote::tx_verification_context &tvc) const;
|
||||
virtual bool execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const;
|
||||
virtual bool revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const;
|
||||
|
||||
static cc_command_handler_destroy_items instance;
|
||||
};
|
||||
|
||||
}
|
@ -53,6 +53,7 @@ const cc_command_base_t *get_cc_command_base(const cc_command_t &cmd)
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_chat_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_create_account_t &cmd) const { return NULL; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_demolish_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_destroy_items_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_dividend_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_event_badge_t &cmd) const { return &cmd; }
|
||||
const cc_command_base_t *operator()(const cryptonote::cc_command_found_city_t &cmd) const { return &cmd; }
|
||||
@ -84,6 +85,7 @@ cc_command_base_t *get_cc_command_base(cc_command_t &cmd)
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_chat_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_create_account_t &cmd) const { return NULL; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_demolish_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_destroy_items_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_dividend_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_event_badge_t &cmd) const { return &cmd; }
|
||||
cc_command_base_t *operator()(cryptonote::cc_command_found_city_t &cmd) const { return &cmd; }
|
||||
|
@ -510,6 +510,18 @@ namespace cryptonote
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct cc_command_destroy_items_t: public cc_command_base_t
|
||||
{
|
||||
uint32_t item_id;
|
||||
uint32_t amount;
|
||||
|
||||
BEGIN_SERIALIZE_OBJECT()
|
||||
FIELDS(*static_cast<cc_command_base_t*>(this))
|
||||
VARINT_FIELD(item_id)
|
||||
VARINT_FIELD(amount)
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
struct cc_command_game_update_t
|
||||
{
|
||||
struct flag_t
|
||||
@ -706,7 +718,8 @@ namespace cryptonote
|
||||
cc_command_dividend_t,
|
||||
cc_command_ignore_t,
|
||||
cc_command_event_badge_t,
|
||||
cc_command_resize_flag_t
|
||||
cc_command_resize_flag_t,
|
||||
cc_command_destroy_items_t
|
||||
> cc_command_t;
|
||||
|
||||
cc_command_base_t *get_cc_command_base(cc_command_t &cmd);
|
||||
@ -820,6 +833,7 @@ CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_dividend_t, (uint8_t)0x13)
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_ignore_t, (uint8_t)0x14);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_event_badge_t, (uint8_t)0x15);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_resize_flag_t, (uint8_t)0x16);
|
||||
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_destroy_items_t, (uint8_t)0x17);
|
||||
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_none_t, (const char*)"none");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_create_account_t, (const char*)"create_account");
|
||||
@ -844,6 +858,7 @@ CC_VARIANT_TAG(json_archive, cryptonote::cc_command_dividend_t, (const char*)"di
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_ignore_t, (const char*)"ignore");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_event_badge_t, (const char*)"event_badge");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_resize_flag_t, (const char*)"resize_flag");
|
||||
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_destroy_items_t, (const char*)"destroy_items");
|
||||
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_none_t, "none");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_create_account_t, "create_account");
|
||||
@ -868,3 +883,4 @@ VARIANT_TAG(debug_archive, cryptonote::cc_command_dividend_t, "dividend");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_ignore_t, "ignore");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_event_badge_t, "event_badge");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_resize_flag_t, "resize_flag");
|
||||
VARIANT_TAG(debug_archive, cryptonote::cc_command_destroy_items_t, "destroy_items");
|
||||
|
@ -289,6 +289,11 @@ bool GameState::process_demolish(const cryptonote::cc_command_demolish_t &cmd, c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameState::process_destroy_items(const cryptonote::cc_command_destroy_items_t &cmd, const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GameState::process_buy_items(const cryptonote::cc_command_buy_items_t &cmd, const std::shared_ptr<GameWallet> &w)
|
||||
{
|
||||
return true;
|
||||
@ -459,6 +464,7 @@ bool GameState::process_command(const cryptonote::cc_command_t &cmd, const std::
|
||||
bool operator()(const cryptonote::cc_command_chat_t &cmd) const { return self.process_chat(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_create_account_t &cmd) const { return self.process_create_account(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_demolish_t &cmd) const { return self.process_demolish(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_destroy_items_t &cmd) const { return self.process_destroy_items(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_dividend_t &cmd) const { return self.process_dividend(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_found_city_t &cmd) const { return self.process_found_city(cmd, w); }
|
||||
bool operator()(const cryptonote::cc_command_game_update_t &cmd) const { return self.process_game_update(cmd, w); }
|
||||
|
@ -140,6 +140,7 @@ private:
|
||||
bool process_chat(const cryptonote::cc_command_chat_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_create_account(const cryptonote::cc_command_create_account_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_demolish(const cryptonote::cc_command_demolish_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_destroy_items(const cryptonote::cc_command_destroy_items_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_dividend(const cryptonote::cc_command_dividend_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_found_city(const cryptonote::cc_command_found_city_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
bool process_game_update(const cryptonote::cc_command_game_update_t &cmd, const std::shared_ptr<GameWallet> &w);
|
||||
|
@ -158,6 +158,7 @@ public:
|
||||
void HandleBuy(StringHash eventType, VariantMap& eventData);
|
||||
void HandleSell(StringHash eventType, VariantMap& eventData);
|
||||
void HandleAssignItems(StringHash eventType, VariantMap& eventData);
|
||||
void HandleDestroyItems(StringHash eventType, VariantMap& eventData);
|
||||
void HandleAddBlock(StringHash eventType, VariantMap& eventData);
|
||||
void HandleRemoveBlock(StringHash eventType, VariantMap& eventData);
|
||||
void HandleDemolish(StringHash eventType, VariantMap& eventData);
|
||||
@ -723,6 +724,7 @@ void CryptoCityUrho3D::SetupUI()
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_BUY, URHO3D_HANDLER(CryptoCityUrho3D, HandleBuy));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_SELL, URHO3D_HANDLER(CryptoCityUrho3D, HandleSell));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_ASSIGN_ITEMS, URHO3D_HANDLER(CryptoCityUrho3D, HandleAssignItems));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_DESTROY_ITEMS, URHO3D_HANDLER(CryptoCityUrho3D, HandleDestroyItems));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_ADD_BLOCK, URHO3D_HANDLER(CryptoCityUrho3D, HandleAddBlock));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_REMOVE_BLOCK, URHO3D_HANDLER(CryptoCityUrho3D, HandleRemoveBlock));
|
||||
SubscribeToEvent(ui, E_CRYPTOCITY_DEMOLISH_FLAG, URHO3D_HANDLER(CryptoCityUrho3D, HandleDemolish));
|
||||
@ -2054,7 +2056,7 @@ void CryptoCityUrho3D::HandleAssignItems(StringHash eventType, VariantMap& event
|
||||
cryptonote::cc_command_assign_items_t cmd;
|
||||
cmd.cc_account = wallet->get_cc_account();
|
||||
cmd.flag = flag->id;
|
||||
const std::vector<std::pair<uint32_t, uint32_t>> *v = (const std::vector<std::pair<uint32_t, uint32_t>>*)eventData[BuyItems::P_QUANTITIES].GetVoidPtr();
|
||||
const std::vector<std::pair<uint32_t, uint32_t>> *v = (const std::vector<std::pair<uint32_t, uint32_t>>*)eventData[AssignItems::P_QUANTITIES].GetVoidPtr();
|
||||
for (const auto &q: *v)
|
||||
{
|
||||
cryptonote::cc_command_assign_items_t::item_t e;
|
||||
@ -2065,6 +2067,24 @@ void CryptoCityUrho3D::HandleAssignItems(StringHash eventType, VariantMap& event
|
||||
wallet->send_command(cmd);
|
||||
}
|
||||
|
||||
void CryptoCityUrho3D::HandleDestroyItems(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
if (!wallet || !wallet->wallet())
|
||||
{
|
||||
new MessageBox(context_, "No wallet loaded - load a wallet to be able to destroy items");
|
||||
return;
|
||||
}
|
||||
const std::vector<std::pair<uint32_t, uint32_t>> *v = (const std::vector<std::pair<uint32_t, uint32_t>>*)eventData[DestroyItems::P_QUANTITIES].GetVoidPtr();
|
||||
for (const auto &q: *v)
|
||||
{
|
||||
cryptonote::cc_command_destroy_items_t cmd;
|
||||
cmd.cc_account = wallet->get_cc_account();
|
||||
cmd.item_id = q.first;
|
||||
cmd.amount = q.second;
|
||||
wallet->send_command(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
void CryptoCityUrho3D::AddBlock(bool use_selection)
|
||||
{
|
||||
UnsetFocus();
|
||||
|
@ -276,6 +276,7 @@ void UIUrho3D::Update(uint32_t mouse_x, uint32_t mouse_y, uint32_t sx0, uint32_t
|
||||
EnableWidget("actions-trade", hasAccount);
|
||||
EnableWidget("actions-research", hasAccount);
|
||||
EnableWidget("actions-assign-items", hasAccount && hasFlagSelected);
|
||||
EnableWidget("actions-destroy-items", hasAccount);
|
||||
|
||||
EnableWidget("actions-approve-build", hasFlagSelected && building);
|
||||
EnableWidget("actions-abandon-build", hasFlagSelected && building);
|
||||
@ -953,6 +954,14 @@ void UIUrho3D::HandleAssignItems(StringHash eventType, VariantMap& eventData)
|
||||
});
|
||||
}
|
||||
|
||||
void UIUrho3D::HandleDestroyItems(StringHash eventType, VariantMap& eventData)
|
||||
{
|
||||
auto *d = new UISelectItemsDialog(context_, gameState, "Select items to destroy");
|
||||
SubscribeToEvent(d, E_SELECT_ITEMS_OKAYED, [this](StringHash eventType, VariantMap& eventData) {
|
||||
SendEvent(E_CRYPTOCITY_DESTROY_ITEMS, eventData);
|
||||
});
|
||||
}
|
||||
|
||||
void UIUrho3D::HandleMaterialSelected(StringHash eventType, VariantMap& eventData, bool player)
|
||||
{
|
||||
const TBSelectList *list = player ? playerMaterialList : flagItemTypeList;
|
||||
@ -1316,6 +1325,7 @@ void UIUrho3D::HandleTBMessage(StringHash eventType, VariantMap& eventData)
|
||||
CONNECT("actions-trade", HandleTrade);
|
||||
CONNECT("actions-research", HandleResearch);
|
||||
CONNECT("actions-assign-items", HandleAssignItems);
|
||||
CONNECT("actions-destroy-items", HandleDestroyItems);
|
||||
CONNECT("actions-demolish", HandleDemolish);
|
||||
CONNECT("actions-undo", HandleUndo);
|
||||
CONNECT("actions-redo", HandleRedo);
|
||||
|
@ -66,6 +66,7 @@ URHO3D_EVENT(E_CRYPTOCITY_BUY_ITEMS, BuyItems) { URHO3D_PARAM(P_QUANTITIES, Quan
|
||||
URHO3D_EVENT(E_CRYPTOCITY_BUY, Buy) { URHO3D_PARAM(P_TYPE, Type); URHO3D_PARAM(P_ID, ID); URHO3D_PARAM(P_AMOUNT, Amount); URHO3D_PARAM(P_PRICE, Price); URHO3D_PARAM(P_ACCRUAL_START_HEIGHT, AccrualStartHeight); URHO3D_PARAM(P_ACCRUAL, Accrual); URHO3D_PARAM(P_ACCRUAL_PRICE_LIMIT, AccrualPriceLimit); URHO3D_PARAM(P_MATCHES, Matches); URHO3D_PARAM(P_COST, Cost); URHO3D_PARAM(P_EXPIRATION, Expiration); }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_SELL, Sell) { URHO3D_PARAM(P_TYPE, Type); URHO3D_PARAM(P_ID, ID); URHO3D_PARAM(P_AMOUNT, Amount); URHO3D_PARAM(P_PRICE, Price); URHO3D_PARAM(P_ACCRUAL_START_HEIGHT, AccrualStartHeight); URHO3D_PARAM(P_ACCRUAL, Accrual); URHO3D_PARAM(P_ACCRUAL_PRICE_LIMIT, AccrualPriceLimit); URHO3D_PARAM(P_MATCHES, Matches); URHO3D_PARAM(P_COST, Cost); URHO3D_PARAM(P_EXPIRATION, Expiration); }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_ASSIGN_ITEMS, AssignItems) { URHO3D_PARAM(P_QUANTITIES, Quantities); /* vector */ }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_DESTROY_ITEMS, DestroyItems) { URHO3D_PARAM(P_QUANTITIES, Quantities); /* vector */ }
|
||||
URHO3D_EVENT(E_CRYPTOCITY_ADD_BLOCK, AddBlock) {}
|
||||
URHO3D_EVENT(E_CRYPTOCITY_REMOVE_BLOCK, RemoveBlock) {}
|
||||
URHO3D_EVENT(E_CRYPTOCITY_APPROVE_BUILD, ApproveBuild) {}
|
||||
@ -151,6 +152,7 @@ private:
|
||||
void HandleAbandonBuild(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleTrade(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleAssignItems(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleDestroyItems(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleMaterialSelected(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData, bool player);
|
||||
void HandlePlayerMaterialSelected(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
void HandleFlagMaterialSelected(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
|
||||
|
@ -5260,6 +5260,45 @@ namespace tools
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_cc_destroy_items(const wallet_rpc::COMMAND_RPC_CC_DESTROY_ITEMS::request& req, wallet_rpc::COMMAND_RPC_CC_DESTROY_ITEMS::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
LOG_PRINT_L3("on_cc_destroy_items starts");
|
||||
if (!m_wallet) return not_open(er);
|
||||
if (m_restricted)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_DENIED;
|
||||
er.message = "Command unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
cryptonote::cc_command_destroy_items_t cmd;
|
||||
cmd.cc_account = m_wallet->get_cc_account();
|
||||
cmd.item_id = req.item_id;
|
||||
cmd.amount = req.amount;
|
||||
uint32_t priority = m_wallet->adjust_priority(req.priority);
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_cc_transactions(cmd, priority);
|
||||
if (ptx_vector.empty())
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
|
||||
er.message = "No transaction created";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string dummy_tx_key;
|
||||
uint64_t dummy_amount;
|
||||
return fill_response(ptx_vector, false, dummy_tx_key, dummy_amount, res.fee, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
class t_daemon
|
||||
|
@ -178,6 +178,7 @@ namespace tools
|
||||
MAP_JON_RPC_WE("cc_ignore", on_cc_ignore, wallet_rpc::COMMAND_RPC_CC_IGNORE)
|
||||
MAP_JON_RPC_WE("cc_event_badge", on_cc_event_badge, wallet_rpc::COMMAND_RPC_CC_EVENT_BADGE)
|
||||
MAP_JON_RPC_WE("cc_resize_flag", on_cc_resize_flag, wallet_rpc::COMMAND_RPC_CC_RESIZE_FLAG)
|
||||
MAP_JON_RPC_WE("cc_destroy_items", on_cc_destroy_items, wallet_rpc::COMMAND_RPC_CC_DESTROY_ITEMS)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
@ -286,6 +287,7 @@ namespace tools
|
||||
bool on_cc_ignore(const wallet_rpc::COMMAND_RPC_CC_IGNORE::request& req, wallet_rpc::COMMAND_RPC_CC_IGNORE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_event_badge(const wallet_rpc::COMMAND_RPC_CC_EVENT_BADGE::request& req, wallet_rpc::COMMAND_RPC_CC_EVENT_BADGE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_resize_flag(const wallet_rpc::COMMAND_RPC_CC_RESIZE_FLAG::request& req, wallet_rpc::COMMAND_RPC_CC_RESIZE_FLAG::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_cc_destroy_items(const wallet_rpc::COMMAND_RPC_CC_DESTROY_ITEMS::request& req, wallet_rpc::COMMAND_RPC_CC_DESTROY_ITEMS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
||||
//json rpc v2
|
||||
bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
@ -3800,5 +3800,50 @@ namespace wallet_rpc
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_CC_DESTROY_ITEMS
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
uint32_t item_id;
|
||||
uint32_t amount;
|
||||
|
||||
uint32_t priority;
|
||||
bool do_not_relay;
|
||||
bool get_tx_hex;
|
||||
bool get_tx_metadata;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(item_id)
|
||||
KV_SERIALIZE(amount)
|
||||
|
||||
KV_SERIALIZE_OPT(priority, (uint32_t)0)
|
||||
KV_SERIALIZE_OPT(do_not_relay, false)
|
||||
KV_SERIALIZE_OPT(get_tx_hex, false)
|
||||
KV_SERIALIZE_OPT(get_tx_metadata, false)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
std::string tx_hash;
|
||||
uint64_t fee;
|
||||
std::string tx_blob;
|
||||
std::string tx_metadata;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash)
|
||||
KV_SERIALIZE(fee)
|
||||
KV_SERIALIZE(tx_blob)
|
||||
KV_SERIALIZE(tx_metadata)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1765,6 +1765,11 @@ class CCTest():
|
||||
from_timestamp = e.timestamp
|
||||
self.test_revert_cmd(daemon, lambda self: self.wallet[3].cc_event_badge(4096, "", "", [{"account_id": 4, "from_level": 2, "to_level": 3, "from_timestamp": from_timestamp}]))
|
||||
|
||||
# destroy items
|
||||
res = daemon.cc_get_custom_items()
|
||||
item_id = res.items_[-1].id
|
||||
self.test_revert_cmd(daemon, lambda self: self.wallet[3].cc_destroy_items(item_id, 2))
|
||||
|
||||
def test_distance_from_generator(self):
|
||||
daemon = Daemon()
|
||||
|
||||
@ -2083,6 +2088,38 @@ class CCTest():
|
||||
assert res.balance == expected_balances[i]
|
||||
assert (res.item_balances if 'item_balances' in res else []) == expected_item_balances[i]
|
||||
|
||||
# testing destruction
|
||||
res = self.wallet[2].cc_destroy_items(ITEM_FIRST_USER + existing_items + 1, 3)
|
||||
expected_balances[2] -= res.fee
|
||||
res = self.wallet[2].cc_destroy_items(ITEM_WOOD, 2)
|
||||
expected_balances[2] -= res.fee
|
||||
self.generate_blocks('CC1MM8HqWBathu8hS5mwMNHm1da3cZCzg2rkqWLKCxpUarKtPszP3MjiocrJeLvph4AghgYu1AXonCmckfEuyE8Q2FFm8jNdiz3', 2)
|
||||
expected_item_balances[2] = self.add_item(expected_item_balances[2], ITEM_FIRST_USER + existing_items + 1, -3)
|
||||
expected_item_balances[2] = self.add_item(expected_item_balances[2], ITEM_WOOD, -2)
|
||||
|
||||
# check total amount
|
||||
res = daemon.cc_get_custom_items()
|
||||
items = [x for x in res.items_ if x['id'] == ITEM_FIRST_USER + existing_items + 1]
|
||||
assert len(items) == 1
|
||||
assert items[0].amount == 30 - 3
|
||||
|
||||
# these can't
|
||||
ok = False
|
||||
try: self.wallet[2].cc_destroy_items(ITEM_FIRST_USER + existing_items + 100, 1)
|
||||
except: ok = True
|
||||
assert ok
|
||||
|
||||
ok = False
|
||||
try: self.wallet[2].cc_destroy_items(ITEM_FIRST_USER + existing_items + 1, 3000000)
|
||||
except: ok = True
|
||||
assert ok
|
||||
|
||||
# check balances
|
||||
for i in range(3):
|
||||
res = daemon.cc_get_account(account_id[i])
|
||||
assert res.balance == expected_balances[i]
|
||||
assert (res.item_balances if 'item_balances' in res else []) == expected_item_balances[i]
|
||||
|
||||
def test_badges(self):
|
||||
daemon = Daemon()
|
||||
|
||||
|
@ -754,6 +754,13 @@ 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)
|
||||
@ -2486,6 +2493,8 @@ TEST(cc, type_tags)
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x15);
|
||||
cmd = cryptonote::cc_command_resize_flag_t();
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x16);
|
||||
cmd = cryptonote::cc_command_destroy_items_t();
|
||||
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x17);
|
||||
}
|
||||
|
||||
TEST(cc, staff)
|
||||
|
@ -1488,3 +1488,19 @@ class Wallet(object):
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_resize_flag)
|
||||
|
||||
def cc_destroy_items(self, item_id, amount, priority = 0, do_not_relay = False, get_tx_hex = False, get_tx_metadata = False):
|
||||
cc_destroy_items = {
|
||||
'method': 'cc_destroy_items',
|
||||
'params': {
|
||||
'item_id': item_id,
|
||||
'amount': amount,
|
||||
'priority': priority,
|
||||
'do_not_relay': do_not_relay,
|
||||
'get_tx_hex': get_tx_hex,
|
||||
'get_tx_metadata': get_tx_metadata,
|
||||
},
|
||||
'jsonrpc': '2.0',
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(cc_destroy_items)
|
||||
|
Loading…
Reference in New Issue
Block a user