forked from townforge/townforge
handle runestones properly on defaulted/derelict buildings
This commit is contained in:
parent
85344d7f42
commit
71c42575fe
@ -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;
|
||||
|
||||
|
@ -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__);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) {}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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()
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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'
|
||||
|
Loading…
Reference in New Issue
Block a user