Add editable player profile

This commit is contained in:
Crypto City 2020-04-07 17:10:57 +00:00
parent b01bc4a258
commit 9153c6f110
30 changed files with 353 additions and 71 deletions

View File

@ -13,30 +13,34 @@ TBTabContainer
TBButton: text: "Discoveries"
TBButton: text: "Badges"
TBLayout: axis: y, distribution: "gravity", distribution-position: "left top"
TBLayout: axis: x, distribution-position: "top", gravity: "top"
TBLayout: axis: y, distribution-position: "top left"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Name:"
TBTextField: id: "name"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Level:"
TBTextField: id: "level"
TBButton: id: "level-up", text: "Level up"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Player ID:"
TBTextField: id: "id"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Public key:"
TBEditField: id: "public_key", readonly: 1, multiline: 0, adapt-to-content: 1, skin: "TBEditField.public-key"
font: size: 12px
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Balance:"
TBTextField: id: "balance"
TBLayout: axis: y, distribution-position: "top right"
TBButton: id: "give-money", text: "Give money"
TBButton: id: "give-items", text: "Give items"
TBSelectList: id: "attributes", gravity: "all"
TBLayout: axis: x, distribution: "gravity"
TBLayout: axis: y, distribution: "gravity", gravity: "top bottom", distribution-position: "left", size: "available"
TBLayout: axis: x, distribution-position: "top", gravity: "top"
TBLayout: axis: y, distribution-position: "top left"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Name:"
TBTextField: id: "name"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Level:"
TBTextField: id: "level"
TBButton: id: "level-up", text: "Level up"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Player ID:"
TBTextField: id: "id"
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Public key:"
TBEditField: id: "public_key", readonly: 1, multiline: 0, adapt-to-content: 1, skin: "TBEditField.public-key"
font: size: 12px
TBLayout: axis: x, distribution-position: "left top"
TBTextField: text: "Balance:"
TBTextField: id: "balance"
TBLayout: axis: y, distribution-position: "top right"
TBButton: id: "give-money", text: "Give money"
TBButton: id: "give-items", text: "Give items"
TBSelectList: id: "attributes"
TBLayout: axis: y, distribution: "gravity"
TBEditField: id: "player-profile", text: "", multiline: 1, gravity: "all", placeholder: "Player profile"
TBButton: id: "save-player-profile", text: "Save"
TBLayout: axis: y, distribution-position: "left top", distribution: "gravity"
TBSelectList: id: "item-balances", gravity: "all"

View File

@ -163,6 +163,7 @@ struct cc_account_data_t
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;
};
@ -1870,6 +1871,7 @@ public:
virtual void set_cc_account_badges(uint32_t id, const std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges) = 0;
virtual void set_cc_account_ignore(uint32_t id, bool ignore) = 0;
virtual void set_cc_account_attributes(uint32_t id, const std::map<uint32_t, uint32_t> &attributes) = 0;
virtual void set_cc_account_desc(uint32_t id, const std::string &s) = 0;
virtual bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const = 0;
virtual uint32_t allocate_new_cc_city(uint32_t ox, uint32_t oy, uint32_t mayor, const std::string &name) = 0;

View File

@ -482,6 +482,7 @@ typedef struct mdb_cc_account_data
uint32_t n_attributes;
bool ignore;
char name[MAX_CC_NAME_LENGTH];
char desc[MAX_CC_DESCRIPTION_LENGTH];
} mdb_cc_account_data;
typedef struct mdb_cc_account_keys_data
@ -581,20 +582,20 @@ typedef struct mdb_cc_custom_item_data_t
uint8_t ignore: 1;
uint8_t padding: 7;
char name[MAX_CC_NAME_LENGTH];
char primary_description[MAX_CC_ITEM_DESCRIPTION_LENGTH];
char secondary_description[MAX_CC_ITEM_DESCRIPTION_LENGTH];
char primary_description[MAX_CC_DESCRIPTION_LENGTH];
char secondary_description[MAX_CC_DESCRIPTION_LENGTH];
} mdb_cc_custom_item_data_t;
typedef struct mdb_cc_event_badge_data_t
{
char name[MAX_CC_NAME_LENGTH];
char desc[MAX_CC_ITEM_DESCRIPTION_LENGTH];
char desc[MAX_CC_DESCRIPTION_LENGTH];
} mdb_cc_event_badge_data_t;
typedef struct mdb_cc_attribute_data_t
{
char name[MAX_CC_NAME_LENGTH];
char description[MAX_CC_ITEM_DESCRIPTION_LENGTH];
char description[MAX_CC_DESCRIPTION_LENGTH];
} mdb_cc_attribute_data_t;
std::atomic<uint64_t> mdb_txn_safe::num_active_txns{0};
@ -4810,6 +4811,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_account(const crypto::public_key &publi
memset(ad.name, 0, sizeof(ad.name));
memcpy(ad.name, name.data(), name.size());
memset(ad.desc, 0, sizeof(ad.desc));
k.mv_data = (void*)&account_id;
k.mv_size = sizeof(account_id);
@ -4943,6 +4945,10 @@ bool BlockchainLMDB::get_cc_account_data(uint32_t id, cc_account_data_t &data) c
const size_t namelen = NUL ? NUL - (const char*)ad->name : MAX_CC_NAME_LENGTH;
data.name.assign(ad->name, namelen);
NUL = (const char*)memchr(ad->desc, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t desclen = NUL ? NUL - (const char*)ad->desc : MAX_CC_DESCRIPTION_LENGTH;
data.description.assign(ad->desc, desclen);
if (!read_account_variable_size_data(ad, v.mv_size, data.item_balances, data.flags, data.badges, data.attributes))
throw0(DB_ERROR("Failed to read account variable size data"));
@ -5211,6 +5217,46 @@ void BlockchainLMDB::set_cc_account_attributes(uint32_t id, const std::map<uint3
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
}
void BlockchainLMDB::set_cc_account_desc(uint32_t id, const std::string &desc)
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
mdb_txn_cursors *m_cursors = &m_wcursors;
if (desc.size() > MAX_CC_DESCRIPTION_LENGTH)
throw0(DB_ERROR("Description is too long"));
CURSOR(cc_accounts)
// find account id
MDB_val_set(k, id);
MDB_val v;
int result = mdb_cursor_get(m_cur_cc_accounts, &k, &v, MDB_SET);
if (result)
throw0(DB_ERROR(lmdb_error("Account " + std::to_string(id) + " not found: ", result).c_str()));
if (v.mv_size < sizeof(mdb_cc_account_data))
throw0(DB_ERROR("Unexpected account data size"));
mdb_cc_account_data ad = *(mdb_cc_account_data*)v.mv_data;
memset(ad.desc, 0, sizeof(ad.desc));
memcpy(ad.desc, desc.data(), desc.size());
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;
if (!read_account_variable_size_data((mdb_cc_account_data*)v.mv_data, v.mv_size, item_balances, flags, badges, attributes))
throw0(DB_ERROR("Failed to read account variable size data"));
write_account_variable_size_data(v, ad, item_balances, flags, badges, attributes);
result = mdb_cursor_put(m_cur_cc_accounts, &k, &v, 0);
free(v.mv_data);
if (result)
throw0(DB_ERROR(lmdb_error("Failed to add account data to db transaction: ", result).c_str()));
}
bool BlockchainLMDB::for_all_cc_accounts(std::function<bool(const cc_account_data_t &data)> f) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
@ -5251,6 +5297,10 @@ bool BlockchainLMDB::for_all_cc_accounts(std::function<bool(const cc_account_dat
const size_t namelen = NUL ? NUL - (const char*)ad.name : MAX_CC_NAME_LENGTH;
data.name.assign(ad.name, namelen);
NUL = (const char*)memchr(ad.desc, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t desclen = NUL ? NUL - (const char*)ad.desc : MAX_CC_DESCRIPTION_LENGTH;
data.description.assign(ad.desc, desclen);
if (!f(data))
{
ret = false;
@ -7079,9 +7129,9 @@ uint32_t BlockchainLMDB::allocate_new_cc_custom_item(uint32_t amount, uint32_t c
if (name.size() > MAX_CC_NAME_LENGTH)
throw0(DB_ERROR("Name is too long"));
if (primary_description.size() > MAX_CC_ITEM_DESCRIPTION_LENGTH)
if (primary_description.size() > MAX_CC_DESCRIPTION_LENGTH)
throw0(DB_ERROR("Description is too long"));
if (secondary_description.size() > MAX_CC_ITEM_DESCRIPTION_LENGTH)
if (secondary_description.size() > MAX_CC_DESCRIPTION_LENGTH)
throw0(DB_ERROR("Description is too long"));
CURSOR(cc_custom_items)
@ -7188,12 +7238,12 @@ bool BlockchainLMDB::get_cc_custom_item_data(uint32_t id, cc::cc_custom_item_t &
const size_t namelen = NUL ? NUL - (const char*)item_data->name : MAX_CC_NAME_LENGTH;
cid.name.assign(item_data->name, namelen);
NUL = (const char*)memchr(item_data->primary_description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t primary_description_len = NUL ? NUL - (const char*)item_data->primary_description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(item_data->primary_description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t primary_description_len = NUL ? NUL - (const char*)item_data->primary_description : MAX_CC_DESCRIPTION_LENGTH;
cid.primary_description.assign(item_data->primary_description, primary_description_len);
NUL = (const char*)memchr(item_data->secondary_description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t secondary_description_len = NUL ? NUL - (const char*)item_data->secondary_description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(item_data->secondary_description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t secondary_description_len = NUL ? NUL - (const char*)item_data->secondary_description : MAX_CC_DESCRIPTION_LENGTH;
cid.secondary_description.assign(item_data->secondary_description, secondary_description_len);
TXN_POSTFIX_RDONLY();
@ -7292,12 +7342,12 @@ bool BlockchainLMDB::for_all_cc_custom_items(std::function<bool(const cc::cc_cus
const size_t namelen = NUL ? NUL - (const char*)item_data.name : MAX_CC_NAME_LENGTH;
cid.name.assign(item_data.name, namelen);
NUL = (const char*)memchr(item_data.primary_description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t primary_description_len = NUL ? NUL - (const char*)item_data.primary_description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(item_data.primary_description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t primary_description_len = NUL ? NUL - (const char*)item_data.primary_description : MAX_CC_DESCRIPTION_LENGTH;
cid.primary_description.assign(item_data.primary_description, primary_description_len);
NUL = (const char*)memchr(item_data.secondary_description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t secondary_description_len = NUL ? NUL - (const char*)item_data.secondary_description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(item_data.secondary_description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t secondary_description_len = NUL ? NUL - (const char*)item_data.secondary_description : MAX_CC_DESCRIPTION_LENGTH;
cid.secondary_description.assign(item_data.secondary_description, secondary_description_len);
if (!f(cid))
@ -7319,7 +7369,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_event_badge(const std::string &name, co
if (name.size() > MAX_CC_NAME_LENGTH)
throw0(DB_ERROR("Name is too long"));
if (desc.size() > MAX_CC_ITEM_DESCRIPTION_LENGTH)
if (desc.size() > MAX_CC_DESCRIPTION_LENGTH)
throw0(DB_ERROR("Description is too long"));
CURSOR(cc_event_badges)
@ -7415,8 +7465,8 @@ bool BlockchainLMDB::get_cc_event_badge_data(uint32_t id, cc::cc_badge_data_t &b
const size_t namelen = NUL ? NUL - (const char*)badge_data->name : MAX_CC_NAME_LENGTH;
bd.name.assign(badge_data->name, namelen);
NUL = (const char*)memchr(badge_data->desc, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)badge_data->desc : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(badge_data->desc, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)badge_data->desc : MAX_CC_DESCRIPTION_LENGTH;
bd.desc.assign(badge_data->desc, description_len);
TXN_POSTFIX_RDONLY();
@ -7457,8 +7507,8 @@ bool BlockchainLMDB::for_all_cc_event_badges(std::function<bool(const cc::cc_bad
const size_t namelen = NUL ? NUL - (const char*)badge_data.name : MAX_CC_NAME_LENGTH;
bd.name.assign(badge_data.name, namelen);
NUL = (const char*)memchr(badge_data.desc, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)badge_data.desc : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(badge_data.desc, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)badge_data.desc : MAX_CC_DESCRIPTION_LENGTH;
bd.desc.assign(badge_data.desc, description_len);
if (!f(bd))
@ -7480,7 +7530,7 @@ uint32_t BlockchainLMDB::allocate_new_cc_attribute(const std::string &name, cons
if (name.size() > MAX_CC_NAME_LENGTH)
throw0(DB_ERROR("Name is too long"));
if (desc.size() > MAX_CC_ITEM_DESCRIPTION_LENGTH)
if (desc.size() > MAX_CC_DESCRIPTION_LENGTH)
throw0(DB_ERROR("Description is too long"));
CURSOR(cc_attributes)
@ -7576,8 +7626,8 @@ bool BlockchainLMDB::get_cc_attribute(uint32_t id, cc_attribute_data_t &ad) cons
const size_t namelen = NUL ? NUL - (const char*)attribute_data->name : MAX_CC_NAME_LENGTH;
ad.name.assign(attribute_data->name, namelen);
NUL = (const char*)memchr(attribute_data->description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)attribute_data->description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(attribute_data->description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)attribute_data->description : MAX_CC_DESCRIPTION_LENGTH;
ad.description.assign(attribute_data->description, description_len);
TXN_POSTFIX_RDONLY();
@ -7618,8 +7668,8 @@ bool BlockchainLMDB::for_all_cc_attributes(std::function<bool(const cc_attribute
const size_t namelen = NUL ? NUL - (const char*)attribute_data.name : MAX_CC_NAME_LENGTH;
ad.name.assign(attribute_data.name, namelen);
NUL = (const char*)memchr(attribute_data.description, 0, MAX_CC_ITEM_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)attribute_data.description : MAX_CC_ITEM_DESCRIPTION_LENGTH;
NUL = (const char*)memchr(attribute_data.description, 0, MAX_CC_DESCRIPTION_LENGTH);
const size_t description_len = NUL ? NUL - (const char*)attribute_data.description : MAX_CC_DESCRIPTION_LENGTH;
ad.description.assign(attribute_data.description, description_len);
if (!f(ad))

View File

@ -486,6 +486,7 @@ private:
void add_cc_account_flag(uint32_t id, uint32_t flag_id);
void remove_cc_account_flag(uint32_t id, uint32_t flag_id);
void set_cc_account_attributes(uint32_t id, const std::map<uint32_t, uint32_t> &attributes);
void set_cc_account_desc(uint32_t id, const std::string &s);
bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const;
uint32_t allocate_new_cc_city(uint32_t ox, uint32_t oy, uint32_t mayor, const std::string &name);

View File

@ -178,6 +178,7 @@ public:
virtual void set_cc_account_badges(uint32_t id, const std::map<uint32_t, std::pair<uint8_t, uint64_t>> &badges) {}
virtual void set_cc_account_ignore(uint32_t id, bool ignore) {}
virtual void set_cc_account_attributes(uint32_t id, const std::map<uint32_t, uint32_t> &attributes) {}
virtual void set_cc_account_desc(uint32_t id, const std::string &s) {}
virtual bool for_all_cc_accounts(std::function<bool(const cc_account_data_t&)>) const { return true; }
virtual uint32_t allocate_new_cc_city(uint32_t ox, uint32_t oy, uint32_t mayor, const std::string &name) { return 0; }

View File

@ -38,6 +38,7 @@ set(cc_sources
cc_command_handler_demolish.cpp
cc_command_handler_destroy_items.cpp
cc_command_handler_dividend.cpp
cc_command_handler_edit_player_profile.cpp
cc_command_handler_event_badge.cpp
cc_command_handler_found_city.cpp
cc_command_handler_game_update.cpp
@ -78,6 +79,7 @@ set(cc_headers
cc_command_handler_demolish.h
cc_command_handler_destroy_items.h
cc_command_handler_dividend.h
cc_command_handler_edit_player_profile.h
cc_command_handler_event_badge.h
cc_command_handler_found_city.h
cc_command_handler_game_update.h

View File

@ -48,6 +48,7 @@
#include "cc_command_handler_demolish.h"
#include "cc_command_handler_destroy_items.h"
#include "cc_command_handler_dividend.h"
#include "cc_command_handler_edit_player_profile.h"
#include "cc_command_handler_found_city.h"
#include "cc_command_handler_game_update.h"
#include "cc_command_handler_give.h"
@ -1712,6 +1713,7 @@ static cc_command_handler &get_cc_command(const cryptonote::cc_command_t &cmd)
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_edit_player_profile_t &cmd) const { return cc_command_handler_edit_player_profile::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; }
cc_command_handler &operator()(const cryptonote::cc_command_game_update_t &cmd) const { return cc_command_handler_game_update::instance; }

View File

@ -54,7 +54,7 @@ bool cc_command_handler_define_attribute::check(const cryptonote::BlockchainDB &
std::string error;
CHECK_COMMAND_SET(define_attribute.name.size() <= MAX_CC_NAME_LENGTH, tvc.m_cc_too_large, "Name is too long");
CHECK_COMMAND_SET(define_attribute.description.size() <= MAX_CC_ITEM_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Description is too long");
CHECK_COMMAND_SET(define_attribute.description.size() <= MAX_CC_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Description is too long");
CHECK_COMMAND_SET(cc::validate_item_name(define_attribute.name, error), tvc.m_cc_forbidden_character, error);
CHECK_COMMAND_SET(!db.lookup_cc_attribute(define_attribute.name, id), tvc.m_cc_conflict, "Attribute already exists");

View File

@ -0,0 +1,92 @@
// 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 "common/utf8.h"
#include "cc/cc_config.h"
#include "cc_command_handler_edit_player_profile.h"
namespace cc
{
cc_command_handler_edit_player_profile cc_command_handler_edit_player_profile::instance;
void cc_command_handler_edit_player_profile::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_edit_player_profile::get_cost(const cryptonote::cc_command_t &cmd) const
{
return 0;
}
bool cc_command_handler_edit_player_profile::check(const cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd, cryptonote::tx_verification_context &tvc) const
{
const cryptonote::cc_command_edit_player_profile_t &edit_player_profile = boost::get<cryptonote::cc_command_edit_player_profile_t>(cmd);
cryptonote::cc_account_data_t ad;
CHECK_COMMAND_SET(edit_player_profile.new_text.size() <= MAX_CC_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Description is too long");
bool valid = true;
try
{
tools::utf8canonical(edit_player_profile.new_text, [&valid](wint_t c)->wint_t {
if (c < 32 && c != '\n')
valid = false;
return c;
});
}
catch(const std::exception &e) { tvc.m_cc_invalid_utf8 = true; MERROR("Invalid UTF-8"); return false; }
CHECK_COMMAND_SET(valid, tvc.m_cc_forbidden_character, "Forbidden character in description");
CHECK_COMMAND_SET(db.get_cc_account_data(edit_player_profile.cc_account, ad), tvc.m_cc_invalid_account, "Account not found");
CHECK_COMMAND_SET(ad.description == edit_player_profile.previous_text, tvc.m_cc_bad_name, "Description does not match existing description");
return true;
}
bool cc_command_handler_edit_player_profile::execute(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_edit_player_profile_t &edit_player_profile = boost::get<cryptonote::cc_command_edit_player_profile_t>(cmd);
db.set_cc_account_desc(edit_player_profile.cc_account, edit_player_profile.new_text);
return true;
}
bool cc_command_handler_edit_player_profile::revert(cryptonote::BlockchainDB &db, const cryptonote::cc_command_t &cmd) const
{
const cryptonote::cc_command_edit_player_profile_t &edit_player_profile = boost::get<cryptonote::cc_command_edit_player_profile_t>(cmd);
db.set_cc_account_desc(edit_player_profile.cc_account, edit_player_profile.previous_text);
return true;
}
}

View 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_edit_player_profile: 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_edit_player_profile instance;
};
}

View File

@ -64,7 +64,7 @@ bool cc_command_handler_event_badge::check(const cryptonote::BlockchainDB &db, c
{
CHECK_COMMAND_SET(event_badge.name.size() <= MAX_CC_NAME_LENGTH, tvc.m_cc_too_large, "Name is too long");
CHECK_COMMAND_SET(!db.is_cc_name_used(event_badge.name, type, id), tvc.m_cc_conflict, "Name already taken");
CHECK_COMMAND_SET(event_badge.description.size() <= MAX_CC_ITEM_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Description is too long");
CHECK_COMMAND_SET(event_badge.description.size() <= MAX_CC_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Description is too long");
CHECK_COMMAND_SET(cc::validate_item_name(event_badge.name, error), tvc.m_cc_forbidden_character, error);
}
for (const auto &e: event_badge.instances)

View File

@ -56,8 +56,8 @@ bool cc_command_handler_new_item::check(const cryptonote::BlockchainDB &db, cons
CHECK_COMMAND_SET(new_item.amount > 0, tvc.m_cc_bad_amount, "Amount is 0");
CHECK_COMMAND_SET(new_item.name.size() <= MAX_CC_NAME_LENGTH, tvc.m_cc_too_large, "Name is too long");
CHECK_COMMAND_SET(!db.is_cc_name_used(new_item.name, type, id), tvc.m_cc_conflict, "Name already taken");
CHECK_COMMAND_SET(new_item.primary_description.size() <= MAX_CC_ITEM_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Primary description is too long");
CHECK_COMMAND_SET(new_item.secondary_description.size() <= MAX_CC_ITEM_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Secondary description is too long");
CHECK_COMMAND_SET(new_item.primary_description.size() <= MAX_CC_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Primary description is too long");
CHECK_COMMAND_SET(new_item.secondary_description.size() <= MAX_CC_DESCRIPTION_LENGTH, tvc.m_cc_too_large, "Secondary description is too long");
CHECK_COMMAND_SET(cc::validate_item_name(new_item.name, error), tvc.m_cc_forbidden_character, error);
CHECK_COMMAND_SET(db.get_cc_account_balance(new_item.cc_account, balance), tvc.m_cc_invalid_account, "Failed to get account balance");
CHECK_COMMAND_SET(balance >= NEW_ITEM_FEE, tvc.m_cc_balance, "Balance too low for the new item creation fee");

View File

@ -63,7 +63,7 @@
#define STAFF_COST 10000000
#define MAX_DISTANCE_PERCENTAGE 1600
#define MAX_CC_NAME_LENGTH 64
#define MAX_CC_ITEM_DESCRIPTION_LENGTH 4096
#define MAX_CC_DESCRIPTION_LENGTH 4096
#define MAX_CC_CHAT_LINE_LENGTH 256
#define CHAT_TIMESTAMP_LEEWAY 20 // seconds
#define NUM_CHAT_COLORS 18

View File

@ -56,6 +56,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_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_edit_player_profile_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; }
const cc_command_base_t *operator()(const cryptonote::cc_command_game_update_t &cmd) const { return NULL; }
@ -90,6 +91,7 @@ cc_command_base_t *get_cc_command_base(cc_command_t &cmd)
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_edit_player_profile_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; }
cc_command_base_t *operator()(cryptonote::cc_command_game_update_t &cmd) const { return NULL; }

View File

@ -546,6 +546,18 @@ namespace cryptonote
END_SERIALIZE()
};
struct cc_command_edit_player_profile_t: public cc_command_base_t
{
std::string previous_text;
std::string new_text;
BEGIN_SERIALIZE_OBJECT()
FIELDS(*static_cast<cc_command_base_t*>(this))
FIELD(previous_text)
FIELD(new_text)
END_SERIALIZE()
};
struct cc_command_game_update_t
{
struct flag_t
@ -745,7 +757,8 @@ namespace cryptonote
cc_command_resize_flag_t,
cc_command_destroy_items_t,
cc_command_define_attribute_t,
cc_command_increase_attribute_t
cc_command_increase_attribute_t,
cc_command_edit_player_profile_t
> cc_command_t;
cc_command_base_t *get_cc_command_base(cc_command_t &cmd);
@ -862,6 +875,7 @@ CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_resize_flag_t, (uint8_t)0x
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_destroy_items_t, (uint8_t)0x17);
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_define_attribute_t, (uint8_t)0x18);
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_increase_attribute_t, (uint8_t)0x19);
CC_VARIANT_TAG(binary_archive, cryptonote::cc_command_edit_player_profile_t, (uint8_t)0x1a);
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");
@ -889,6 +903,7 @@ CC_VARIANT_TAG(json_archive, cryptonote::cc_command_resize_flag_t, (const char*)
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_destroy_items_t, (const char*)"destroy_items");
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_define_attribute_t, (const char*)"define_attribute");
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_increase_attribute_t, (const char*)"increase_attribute");
CC_VARIANT_TAG(json_archive, cryptonote::cc_command_edit_player_profile_t, (const char*)"edit_player_profile");
VARIANT_TAG(debug_archive, cryptonote::cc_command_none_t, "none");
VARIANT_TAG(debug_archive, cryptonote::cc_command_create_account_t, "create_account");
@ -916,3 +931,4 @@ VARIANT_TAG(debug_archive, cryptonote::cc_command_resize_flag_t, "resize_flag");
VARIANT_TAG(debug_archive, cryptonote::cc_command_destroy_items_t, "destroy_items");
VARIANT_TAG(debug_archive, cryptonote::cc_command_define_attribute_t, "define_attribute");
VARIANT_TAG(debug_archive, cryptonote::cc_command_increase_attribute_t, "increase_attribute");
VARIANT_TAG(debug_archive, cryptonote::cc_command_edit_player_profile_t, "edit_player_profile");

View File

@ -52,7 +52,7 @@ void PlayerState::update(const std::shared_ptr<GameWallet> &wallet)
id = w->get_cc_account();
if (id)
{
w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignored);
w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignored);
}
else
{
@ -346,6 +346,13 @@ bool GameState::process_dividend(const cryptonote::cc_command_dividend_t &cmd, c
return true;
}
bool GameState::process_edit_player_profile(const cryptonote::cc_command_edit_player_profile_t &cmd, const std::shared_ptr<GameWallet> &w)
{
if (cmd.cc_account == playerState.id)
playerState.description = cmd.new_text;
return true;
}
bool GameState::process_found_city(const cryptonote::cc_command_found_city_t &cmd, const std::shared_ptr<GameWallet> &w)
{
cities.push_back({});
@ -478,6 +485,7 @@ bool GameState::process_command(const cryptonote::cc_command_t &cmd, const std::
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_edit_player_profile_t &cmd) const { return self.process_edit_player_profile(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); }
bool operator()(const cryptonote::cc_command_give_t &cmd) const { return self.process_give(cmd, w); }

View File

@ -19,6 +19,7 @@ URHO3D_EVENT(E_CRYPTOCITY_REQUEST_PLAYER_DATA, RequestPlayerData)
URHO3D_PARAM(P_PUBLIC_KEY, PublicKey);
URHO3D_PARAM(P_BALANCE, Balance);
URHO3D_PARAM(P_NAME, Name);
URHO3D_PARAM(P_DESCRIPTION, Description);
URHO3D_PARAM(P_ITEM_BALANCES, ItemBalances);
URHO3D_PARAM(P_FLAGS, Flags);
URHO3D_PARAM(P_BADGES, Badges);
@ -73,6 +74,7 @@ struct PlayerState
uint64_t wallet_unlocked_balance;
std::string public_key;
std::string name;
std::string description;
std::map<uint32_t, uint32_t> item_balances;
std::vector<uint32_t> flags;
std::map<uint32_t, std::pair<uint8_t, uint64_t>> badges;
@ -145,6 +147,7 @@ private:
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_edit_player_profile(const cryptonote::cc_command_edit_player_profile_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);
bool process_give(const cryptonote::cc_command_give_t &cmd, const std::shared_ptr<GameWallet> &w);

View File

@ -275,7 +275,7 @@ public:
void requestSnapshot(uint32_t city_id);
uint32_t get_cc_account();
bool get_cc_account_data(uint32_t id, std::string &name);
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, bool &ignore);
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);
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, std::string &primary_description, std::string &secondary_description, bool &ignore);
bool get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc::cc_badge_data_t> &data);
@ -881,9 +881,9 @@ uint32_t GameWalletInternal::get_cc_account()
return w->get_cc_account();
}
bool GameWalletInternal::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, bool &ignore)
bool GameWalletInternal::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)
{
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignore))
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore))
return false;
return true;
}
@ -896,8 +896,9 @@ bool GameWalletInternal::get_cc_account_data(uint32_t id, std::string &name)
std::map<uint32_t, std::pair<uint8_t, uint64_t>> badges;
std::map<uint32_t, uint32_t> attributes;
std::string public_key;
std::string description;
bool ignore;
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignore))
if (!w->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore))
return false;
return true;
}
@ -1391,9 +1392,9 @@ bool GameWallet::get_cc_account_data(uint32_t id, std::string &name)
return internal->get_cc_account_data(id, name);
}
bool GameWallet::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, bool &ignore)
bool GameWallet::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)
{
return internal->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignore);
return internal->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore);
}
bool GameWallet::get_cc_custom_item_data(uint32_t id, uint32_t &creator, uint32_t &amount, std::string &name, std::string &primary_description, std::string &secondary_description, bool &ignore)

View File

@ -47,7 +47,7 @@ public:
void requestSnapshot(uint32_t city_id);
uint32_t get_cc_account();
bool get_cc_account_data(uint32_t id, std::string &name);
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, bool &ignore);
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);
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, std::string &primary_description, std::string &secondary_description, bool &ignore);
bool get_cc_badge_data(const std::vector<uint32_t> &id, std::vector<cc::cc_badge_data_t> &data);

View File

@ -161,6 +161,7 @@ public:
void HandleDestroyItems(StringHash eventType, VariantMap& eventData);
void HandleDefineAttribute(StringHash eventType, VariantMap& eventData);
void HandleIncreaseAttribute(StringHash eventType, VariantMap& eventData);
void HandleSavePlayerProfile(StringHash eventType, VariantMap& eventData);
void HandleAddBlock(StringHash eventType, VariantMap& eventData);
void HandleRemoveBlock(StringHash eventType, VariantMap& eventData);
void HandleDemolish(StringHash eventType, VariantMap& eventData);
@ -729,6 +730,7 @@ void CryptoCityUrho3D::SetupUI()
SubscribeToEvent(ui, E_CRYPTOCITY_DESTROY_ITEMS, URHO3D_HANDLER(CryptoCityUrho3D, HandleDestroyItems));
SubscribeToEvent(ui, E_CRYPTOCITY_DEFINE_ATTRIBUTE, URHO3D_HANDLER(CryptoCityUrho3D, HandleDefineAttribute));
SubscribeToEvent(ui, E_CRYPTOCITY_INCREASE_ATTRIBUTE, URHO3D_HANDLER(CryptoCityUrho3D, HandleIncreaseAttribute));
SubscribeToEvent(ui, E_CRYPTOCITY_SAVE_PLAYER_PROFILE, URHO3D_HANDLER(CryptoCityUrho3D, HandleSavePlayerProfile));
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));
@ -2121,6 +2123,21 @@ void CryptoCityUrho3D::HandleIncreaseAttribute(StringHash eventType, VariantMap&
}
}
void CryptoCityUrho3D::HandleSavePlayerProfile(StringHash eventType, VariantMap& eventData)
{
if (!wallet || !wallet->wallet())
{
new MessageBox(context_, "No wallet loaded - load a wallet to be able to save your player profile");
return;
}
cryptonote::cc_command_edit_player_profile_t cmd;
cmd.cc_account = wallet->get_cc_account();
cmd.previous_text = gameState.playerState.description;
cmd.new_text = eventData[SavePlayerProfile::P_PROFILE].GetString().CString();
wallet->send_command(cmd);
}
void CryptoCityUrho3D::AddBlock(bool use_selection)
{
UnsetFocus();
@ -3854,7 +3871,7 @@ void CryptoCityUrho3D::HandleRequestPlayerData(StringHash eventType, VariantMap&
if (wallet)
{
const uint32_t id = eventData[RequestPlayerData::P_ACCOUNT].GetUInt();
std::string name;
std::string name, description;
std::string public_key;
uint64_t balance;
std::map<uint32_t, uint32_t> item_balances;
@ -3862,12 +3879,13 @@ void CryptoCityUrho3D::HandleRequestPlayerData(StringHash eventType, VariantMap&
std::map<uint32_t, std::pair<uint8_t, uint64_t>> badges;
std::map<uint32_t, uint32_t> attributes;
bool ignore;
if (wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignore))
if (wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore))
{
gameState.set_player_name(id, name, ignore);
eventData[RequestPlayerData::P_PUBLIC_KEY] = public_key.c_str();
eventData[RequestPlayerData::P_NAME] = gameState.get_player_name(id).c_str();
eventData[RequestPlayerData::P_DESCRIPTION] = description.c_str();
eventData[RequestPlayerData::P_BALANCE] = (unsigned long long)balance;
Vector<VariantMap> ItemBalances; for (const auto &e: item_balances) ItemBalances.Push(make_item_balance_variant(e));
eventData[RequestPlayerData::P_ITEM_BALANCES] = ItemBalances;
@ -4120,9 +4138,9 @@ void CryptoCityUrho3D::HandleEventBadge(StringHash eventType, VariantMap& eventD
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 name, description;
bool ignore;
if (!wallet->get_cc_account_data(e.first, public_key, balance, item_balances, flags, badges, attributes, name, ignore))
if (!wallet->get_cc_account_data(e.first, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore))
{
new MessageBox(context_, "Failed to get account data for recipient");
return;

View File

@ -588,6 +588,8 @@ UIPlayerInfoDialog::UIPlayerInfoDialog(Context *ctx, const GameState *game, uint
discoveriesSearchWidget = GetWidgetByIDAndType<TBEditField>(TBIDC("discoveries-search"));
badgesWidget = GetWidgetByIDAndType<TBSelectList>(TBIDC("badges"));
levelUpWidget = GetWidgetByIDAndType<TBButton>(TBIDC("level-up"));
playerProfileWidget = GetWidgetByIDAndType<TBEditField>(TBIDC("player-profile"));
savePlayerProfileWidget = GetWidgetByIDAndType<TBButton>(TBIDC("save-player-profile"));
flagsWidget->SetHeader(flagsHeaderWidget = new FlagListHeaderWidget(context_), true);
SubscribeToEvent(flagsHeaderWidget, E_LIST_HEADER_RESIZED, URHO3D_HANDLER(UIPlayerInfoDialog, HandleListHeaderResized));
@ -612,6 +614,10 @@ UIPlayerInfoDialog::UIPlayerInfoDialog(Context *ctx, const GameState *game, uint
button->SetState(WIDGET_STATE_DISABLED, true);
}
const bool can_edit = game->playerState.has_wallet && game->playerState.id == player_id;
playerProfileWidget->SetReadOnly(!can_edit);
savePlayerProfileWidget->SetVisibility(can_edit ? WIDGET_VISIBILITY_VISIBLE : WIDGET_VISIBILITY_INVISIBLE);
SubscribeToEvent(this, E_TB_WIDGET_EVENT, URHO3D_HANDLER(UIPlayerInfoDialog, HandleTBMessage));
SubscribeToEvent(this, E_TB_WINDOW_CLOSED, URHO3D_HANDLER(UIPlayerInfoDialog, HandleClose));
}
@ -664,6 +670,7 @@ void UIPlayerInfoDialog::FillData(const std::shared_ptr<GameWallet> &w, uint32_t
SendEvent(E_CRYPTOCITY_REQUEST_PLAYER_DATA, eventData);
String name = eventData[RequestPlayerData::P_NAME].GetString();
String description = eventData[RequestPlayerData::P_DESCRIPTION].GetString();
uint64_t balance = eventData[RequestPlayerData::P_BALANCE].GetUInt64();
Vector<VariantMap> item_balances = eventData[RequestPlayerData::P_ITEM_BALANCES].GetVariantMapVector();
Vector<VariantMap> flags = eventData[RequestPlayerData::P_FLAGS].GetVariantMapVector();
@ -681,6 +688,8 @@ void UIPlayerInfoDialog::FillData(const std::shared_ptr<GameWallet> &w, uint32_t
}
nameWidget->SetText(name.CString());
if (!game->ignore_player(player_id))
playerProfileWidget->SetText(description.CString());
levelWidget->SetText(std::to_string(cc::get_badge_score(badge_count).second));
idWidget->SetText(String(player_id).CString());
publicKeyWidget->SetText(public_key.c_str());
@ -893,6 +902,13 @@ void UIPlayerInfoDialog::HandleLevelUp(StringHash eventType, VariantMap& eventDa
});
}
void UIPlayerInfoDialog::HandleSavePlayerProfile(StringHash eventType, VariantMap& eventData)
{
VariantMap saveEventData;
saveEventData[PlayerInfoSavePlayerProfile::P_PROFILE] = playerProfileWidget->GetText().CStr();
SendEvent(E_PLAYER_INFO_SAVE_PLAYER_PROFILE, saveEventData);
}
void UIPlayerInfoDialog::HandleTBMessage(StringHash eventType, VariantMap& eventData)
{
#define CONNECT(name, function) do { if (ev->target->GetID() == TBIDC(name)) function(eventType, eventData); } while(0)
@ -904,6 +920,7 @@ void UIPlayerInfoDialog::HandleTBMessage(StringHash eventType, VariantMap& event
CONNECT("give-items", HandleGiveItems);
CONNECT("give-money", HandleGiveMoney);
CONNECT("level-up", HandleLevelUp);
CONNECT("save-player-profile", HandleSavePlayerProfile);
HeaderButton *hb = TBSafeCast<HeaderButton>(ev->target);
if (hb)

View File

@ -31,6 +31,7 @@ class UIIncreaseAttributeDialog;
URHO3D_EVENT(E_PLAYER_INFO_CLOSED, PlayerInfoClosed) {}
URHO3D_EVENT(E_PLAYER_INFO_FLAG_SELECTED, PlayerInfoFlagSelected) { URHO3D_PARAM(P_FLAG, Flag); }
URHO3D_EVENT(E_PLAYER_INFO_SAVE_PLAYER_PROFILE, PlayerInfoSavePlayerProfile) { URHO3D_PARAM(P_PROFILE, Profile); }
class UIPlayerInfoDialog: public UITBWindow
{
@ -57,6 +58,7 @@ private:
void HandleListHeaderResized(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleFlagList(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleLevelUp(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void HandleSavePlayerProfile(Urho3D::StringHash eventType, Urho3D::VariantMap& eventData);
void InitColumnsList();
void FillData(const std::shared_ptr<GameWallet> &w, uint32_t player_id);
@ -179,6 +181,8 @@ private:
tb::TBSelectList *badgesWidget;
tb::TBButton *levelUpWidget;
tb::TBSelectList *attributesWidget;
tb::TBEditField *playerProfileWidget;
tb::TBButton *savePlayerProfileWidget;
uint32_t player_id;
std::string last_refresh_stop_hash;

View File

@ -1510,6 +1510,9 @@ void UIUrho3D::ShowPlayerInfo(uint32_t player_id)
SubscribeToEvent(playerInfoDialog, E_CRYPTOCITY_INCREASE_ATTRIBUTE, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_INCREASE_ATTRIBUTE, eventData);
});
SubscribeToEvent(playerInfoDialog, E_PLAYER_INFO_SAVE_PLAYER_PROFILE, [this](StringHash eventType, VariantMap& eventData) {
SendEvent(E_CRYPTOCITY_SAVE_PLAYER_PROFILE, eventData);
});
}
void UIUrho3D::HandleCloseCommandWindow(StringHash eventType, VariantMap& eventData)

View File

@ -113,6 +113,7 @@ URHO3D_EVENT(E_CRYPTOCITY_CONTROLS_CHANGED, ControlsChanged) {}
URHO3D_EVENT(E_CRYPTOCITY_SELECT_EXTEND, SelectExtend) { URHO3D_PARAM(P_DX0, DX0); URHO3D_PARAM(P_DY0, DY0); URHO3D_PARAM(P_DX1, DX1); URHO3D_PARAM(P_DY1, DY1); }
URHO3D_EVENT(E_CRYPTOCITY_DEFINE_ATTRIBUTE, DefineAttribute) { URHO3D_PARAM(P_NAME, Name); URHO3D_PARAM(P_DESCRIPTION, Description); }
URHO3D_EVENT(E_CRYPTOCITY_INCREASE_ATTRIBUTE, IncreaseAttribute) { URHO3D_PARAM(P_ATTRIBUTES, Attributes); /* vector */ }
URHO3D_EVENT(E_CRYPTOCITY_SAVE_PLAYER_PROFILE, SavePlayerProfile) { URHO3D_PARAM(P_PROFILE, Profile); }
class UIUrho3D: public Urho3D::UIElement
{

View File

@ -3426,6 +3426,7 @@ namespace cryptonote
}
res.balance = data.balance;
res.name = std::move(data.name);
res.description = std::move(data.description);
res.ignore = data.ignore;
res.public_key = epee::string_tools::pod_to_hex(data.public_key);
for (const auto &e: data.item_balances)

View File

@ -2775,6 +2775,7 @@ namespace cryptonote
std::vector<badge_t> badges;
std::vector<attribute_t> attributes;
std::string name;
std::string description;
bool ignore;
std::string status;
@ -2786,6 +2787,7 @@ namespace cryptonote
KV_SERIALIZE(badges)
KV_SERIALIZE(attributes)
KV_SERIALIZE(name)
KV_SERIALIZE(description)
KV_SERIALIZE(ignore)
KV_SERIALIZE(status)
END_KV_SERIALIZE_MAP()

View File

@ -2945,13 +2945,14 @@ bool simple_wallet::cc_status(const std::vector<std::string> &args_)
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 name, description;
std::string public_key;
bool ignore;
m_wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, ignore);
m_wallet->get_cc_account_data(id, public_key, balance, item_balances, flags, badges, attributes, name, description, ignore);
message_writer() << tr("Account number: ") << id << " (" << tr("address: ") << m_wallet->get_cc_pkey() << ")";
message_writer() << tr("Name: ") << name;
message_writer() << tr("Description: ") << description;
message_writer() << tr("Balance: ") << cryptonote::print_money(balance);

View File

@ -917,7 +917,7 @@ private:
// CC
bool get_new_cc_flag_cost(uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint64_t &cost);
bool get_cc_build_budget(uint32_t flag, uint32_t dx, uint32_t dy, uint32_t width, uint32_t height, uint16_t min_height, const std::vector<uint8_t> &tiles, bool encoded, std::map<uint32_t, uint32_t> &budget);
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, bool &ignore);
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);
bool get_cc_city_data(uint32_t id, uint32_t &ox, uint32_t &oy, uint32_t &treasury, uint32_t &mayor, std::string &name, uint64_t &treasury_balance, uint32_t &max_level);
bool get_cc_special_events(uint32_t city, bool all, std::vector<cc::special_event_data_t> &special_events);
bool get_cc_snapshot(cryptonote::cc_snapshot &snapshot, uint32_t city_id, uint64_t &height, crypto::hash &top_hash, std::vector<cryptonote::cc_command_t> &top_commands);

View File

@ -106,7 +106,7 @@ bool wallet2::get_cc_build_budget(uint32_t flag, uint32_t dx, uint32_t dy, uint3
return true;
}
bool wallet2::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, bool &ignore)
bool wallet2::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)
{
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::request req = AUTO_VAL_INIT(req);
cryptonote::COMMAND_RPC_CC_GET_ACCOUNT::response res;
@ -131,7 +131,8 @@ bool wallet2::get_cc_account_data(uint32_t id, std::string &public_key, uint64_t
attributes.clear();
for (const auto &e: res.attributes)
attributes[e.type] = e.value;
name = res.name;
name = std::move(res.name);
description = std::move(res.description);
ignore = res.ignore;
return true;
}

View File

@ -2499,6 +2499,8 @@ TEST(cc, type_tags)
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x18);
cmd = cryptonote::cc_command_increase_attribute_t();
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x19);
cmd = cryptonote::cc_command_edit_player_profile_t();
ASSERT_EQ(get_cc_tag<uint8_t>(cmd), 0x1a);
}
TEST(cc, staff)