handle runestones properly on defaulted/derelict buildings

This commit is contained in:
Crypto City 2021-04-05 15:59:19 +00:00
parent 85344d7f42
commit 71c42575fe
11 changed files with 124 additions and 4 deletions

View File

@ -2123,6 +2123,7 @@ public:
virtual void add_cc_runestone(const cc::runestone_t &runestone) = 0;
virtual bool get_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h, cc::runestone_t &runestone) const = 0;
virtual bool get_cc_runestones(uint32_t flag, std::vector<cc::runestone_t> &runestones) const = 0;
virtual bool for_all_cc_runestones(const std::function<bool(const cc::runestone_t&)> &f) const = 0;
virtual void remove_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h) = 0;

View File

@ -9921,6 +9921,57 @@ bool BlockchainLMDB::get_cc_runestone(uint32_t flag, uint8_t x, uint8_t y, uint1
return true;
}
bool BlockchainLMDB::get_cc_runestones(uint32_t flag, std::vector<cc::runestone_t> &runestones) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
check_open();
TXN_PREFIX_RDONLY();
RCURSOR(cc_runestones);
runestones.clear();
const uint64_t key = (((uint64_t)flag) << 32) | (((uint64_t)0) << 24) | (((uint64_t)0) << 16) | (uint64_t)0;
MDB_val k = {sizeof(key), (void *)&key};
MDB_val v;
MDB_cursor_op op = MDB_SET_RANGE;
while (1)
{
int result = mdb_cursor_get(m_cur_cc_runestones, &k, &v, op);
if (result == MDB_NOTFOUND)
return true;
if (result)
throw0(DB_ERROR(lmdb_error("Error attempting to retrieve runestone data: ", result).c_str()));
op = MDB_NEXT;
const uint64_t &rk = *(const uint64_t*)k.mv_data;
if (((rk >> 32) & 0xffffffff) != flag)
break;
mdb_cc_runestone_data_t rd;
if (!read_runestone_data(v, rd))
throw0(DB_ERROR("Failed to deserialize runestone data"));
runestones.push_back({});
auto &runestone = runestones.back();
runestone.flag = (rk >> 32) & 0xffffffff;
runestone.x = (rk >> 24) & 0xff;
runestone.y = (rk >> 16) & 0xff;
runestone.h = (rk >> 0) & 0xffff;
runestone.script = rd.script;
runestone.message = std::move(rd.message);
runestone.overrides.reserve(rd.overrides.size());
for (auto &e: rd.overrides)
runestone.overrides.push_back(std::make_tuple(e.type, e.idx, std::move(e.text)));
}
TXN_POSTFIX_RDONLY();
return true;
}
bool BlockchainLMDB::for_all_cc_runestones(const std::function<bool(const cc::runestone_t&)> &f) const
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);

View File

@ -667,6 +667,7 @@ private:
virtual void add_cc_runestone(const cc::runestone_t &runestone);
virtual bool get_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h, cc::runestone_t &runestone) const;
virtual bool get_cc_runestones(uint32_t flag, std::vector<cc::runestone_t> &runestones) const;
virtual bool for_all_cc_runestones(const std::function<bool(const cc::runestone_t&)> &f) const;
virtual void remove_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h);

View File

@ -326,6 +326,7 @@ public:
virtual void add_cc_runestone(const cc::runestone_t &runestone) {}
virtual bool get_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h, cc::runestone_t &runestone) const { return false; }
virtual bool get_cc_runestones(uint32_t flag, std::vector<cc::runestone_t> &runestones) const { return false; }
virtual bool for_all_cc_runestones(const std::function<bool(const cc::runestone_t&)> &f) const { return false; }
virtual void remove_cc_runestone(uint32_t flag, uint8_t dx, uint8_t dy, uint16_t h) {}

View File

@ -145,6 +145,8 @@ static bool execute_city(cryptonote::BlockchainDB &db, const cryptonote::cc_comm
}
for (const auto &derelict: city.derelict)
{
for (const auto &e: derelict.runestones)
db.remove_cc_runestone(derelict.id, e.x, e.y, e.h);
db.remove_cc_flag_blocks(derelict.id);
db.set_cc_flag_repair(derelict.id, 0);
db.set_cc_flag_role(derelict.id, ROLE_EMPTY, 0);
@ -152,6 +154,8 @@ static bool execute_city(cryptonote::BlockchainDB &db, const cryptonote::cc_comm
}
for (const auto &defaulted: city.defaulted)
{
for (const auto &e: defaulted.runestones)
db.remove_cc_runestone(defaulted.id, e.x, e.y, e.h);
db.set_cc_flag_role(defaulted.id, ROLE_EMPTY, 0);
db.remove_cc_account_flag(defaulted.owner, defaulted.id);
db.delete_cc_flag(defaulted.id);
@ -519,6 +523,8 @@ static bool revert_city(cryptonote::BlockchainDB &db, const cryptonote::cc_comma
db.set_cc_flag_nutrients(f.id, f.vegetables_nutrients, f.grain_nutrients);
db.set_cc_flag_num_missed_ticks(f.id, f.num_missed_ticks);
db.set_cc_flag_mortgage(f.id, f.mortgage);
for (const auto &r: f.runestones)
db.add_cc_runestone({f.id, r.x, r.y, r.h, r.script, r.message, r.overrides});
return true;
};
for (const auto &defaulted: city.defaulted)

View File

@ -462,7 +462,13 @@ static void add_cities(const BlockchainDB &db, cc_command_game_update_t &cg, gam
std::vector<cc_command_game_update_t::flag_t::budget_item_t> budget;
for (const auto &e: fd.budget)
budget.push_back({e.first, e.second});
cg.cities.back().defaulted.push_back({flag.id, fd.owner, fd.city, fd.role, fd.x0, fd.y0, fd.x1, fd.y1, fd.repair, fd.economic_power, fd.construction_height, fd.fire_state, fd.name, fd.ignore, fd.active, fd.last_service_height, fd.service_price, fd.crop, fd.sow_height, fd.vegetables_nutrients, fd.grain_nutrients, fd.mortgage, fd.num_missed_ticks, fd.palette, fd.tiles, std::move(budget)});
std::vector<cc::runestone_t> runestones;
CHECK_AND_ASSERT_THROW_MES(db.get_cc_runestones(flag.id, runestones), "Failed to lookup runestones");
std::vector<cc_command_game_update_t::flag_t::runestone_item_t> runestone_data;
runestone_data.reserve(runestones.size());
for (auto &e: runestones)
runestone_data.push_back({e.x, e.y, e.h, e.script, std::move(e.message), std::move(e.overrides)});
cg.cities.back().defaulted.push_back({flag.id, fd.owner, fd.city, fd.role, fd.x0, fd.y0, fd.x1, fd.y1, fd.repair, fd.economic_power, fd.construction_height, fd.fire_state, fd.name, fd.ignore, fd.active, fd.last_service_height, fd.service_price, fd.crop, fd.sow_height, fd.vegetables_nutrients, fd.grain_nutrients, fd.mortgage, fd.num_missed_ticks, fd.palette, fd.tiles, std::move(budget), std::move(runestone_data)});
q.remove(v[i]);
v.erase(v.begin() + i);
@ -1079,7 +1085,13 @@ static void add_cities(const BlockchainDB &db, cc_command_game_update_t &cg, gam
std::vector<cc_command_game_update_t::flag_t::budget_item_t> budget;
for (const auto &e: fd.budget)
budget.push_back({e.first, e.second});
cg.cities.back().derelict.push_back({flag.id, fd.owner, fd.city, fd.role, fd.x0, fd.y0, fd.x1, fd.y1, fd.repair, fd.economic_power, fd.construction_height, fd.fire_state, fd.name, fd.ignore, fd.active, fd.last_service_height, fd.service_price, fd.crop, fd.sow_height, fd.vegetables_nutrients, fd.grain_nutrients, fd.mortgage, fd.num_missed_ticks, fd.palette, fd.tiles, std::move(budget)});
std::vector<cc::runestone_t> runestones;
CHECK_AND_ASSERT_THROW_MES(db.get_cc_runestones(flag.id, runestones), "Failed to lookup runestones");
std::vector<cc_command_game_update_t::flag_t::runestone_item_t> runestone_data;
runestone_data.reserve(runestones.size());
for (auto &e: runestones)
runestone_data.push_back({e.x, e.y, e.h, e.script, std::move(e.message), std::move(e.overrides)});
cg.cities.back().derelict.push_back({flag.id, fd.owner, fd.city, fd.role, fd.x0, fd.y0, fd.x1, fd.y1, fd.repair, fd.economic_power, fd.construction_height, fd.fire_state, fd.name, fd.ignore, fd.active, fd.last_service_height, fd.service_price, fd.crop, fd.sow_height, fd.vegetables_nutrients, fd.grain_nutrients, fd.mortgage, fd.num_missed_ticks, fd.palette, fd.tiles, std::move(budget), std::move(runestone_data)});
cg.cities.back().fire.push_back({flag.id, 0 - (int32_t)flag.fire_state});
flag.fire_state = 0;

View File

@ -1132,6 +1132,25 @@ namespace cryptonote
END_SERIALIZE()
};
struct runestone_item_t
{
uint8_t x;
uint8_t y;
uint16_t h;
uint32_t script;
std::string message;
std::vector<std::tuple<uint8_t, uint32_t, std::string>> overrides;
BEGIN_SERIALIZE_OBJECT()
FIELD(x)
FIELD(y)
VARINT_FIELD(h)
VARINT_FIELD(script)
FIELD(message)
FIELD(overrides)
END_SERIALIZE()
};
uint32_t id;
uint32_t owner;
uint32_t city;
@ -1158,6 +1177,7 @@ namespace cryptonote
std::vector<uint16_t> palette;
std::vector<uint8_t> tiles;
std::vector<budget_item_t> budget;
std::vector<runestone_item_t> runestones;
BEGIN_SERIALIZE_OBJECT()
VARINT_FIELD(id)
@ -1186,6 +1206,7 @@ namespace cryptonote
FIELD(palette)
FIELD(tiles)
FIELD(budget)
FIELD(runestones)
END_SERIALIZE()
};

View File

@ -5423,7 +5423,25 @@ namespace cryptonote
overrides.reserve(runestone.overrides.size());
for (auto &e: runestone.overrides)
overrides.push_back({std::get<0>(e), std::get<1>(e), std::move(std::get<2>(e))});
res.runestones.push_back({l.flag, l.x, l.y, l.h, runestone.script, std::move(runestone.message), std::move(overrides)});
res.runestones.push_back({runestone.flag, runestone.x, runestone.y, runestone.h, runestone.script, std::move(runestone.message), std::move(overrides)});
}
if (req.flag)
{
std::vector<cc::runestone_t> runestones;
if (!db.get_cc_runestones(req.flag, runestones))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Error getting runestone data";
return false;
}
for (auto &runestone: runestones)
{
std::vector<COMMAND_RPC_CC_GET_RUNESTONES::override_t> overrides;
overrides.reserve(runestone.overrides.size());
for (auto &e: runestone.overrides)
overrides.push_back({std::get<0>(e), std::get<1>(e), std::move(std::get<2>(e))});
res.runestones.push_back({runestone.flag, runestone.x, runestone.y, runestone.h, runestone.script, std::move(runestone.message), std::move(overrides)});
}
}
}
catch (const std::exception &e)

View File

@ -4689,9 +4689,11 @@ namespace cryptonote
struct request_t
{
std::vector<location_t> locations;
uint32_t flag;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(locations)
KV_SERIALIZE_OPT(flag, (uint32_t)0)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<request_t> request;

View File

@ -805,6 +805,12 @@ public:
state.item_count.erase(id);
}
virtual bool get_cc_runestones(uint32_t flag, std::vector<cc::runestone_t> &runestones) const
{
runestones.clear();
return true;
}
private:
std::vector<block_t> blocks;
state_t state;

View File

@ -1117,11 +1117,12 @@ class Daemon(object):
}
return self.rpc.send_json_rpc_request(cc_get_foreclosures)
def cc_get_runestones(self, locations):
def cc_get_runestones(self, locations= [], flag = 0):
cc_get_runestones = {
'method': 'cc_get_runestones',
'params': {
'locations': locations,
'flag': flag,
},
'jsonrpc': '2.0',
'id': '0'