solanaceae_ngc_ft1/solanaceae/ngc_ft1_sha1/re_announce_systems.cpp

85 lines
2.6 KiB
C++

#include "./re_announce_systems.hpp"
#include "./components.hpp"
#include <solanaceae/object_store/meta_components_file.hpp>
#include <solanaceae/tox_contacts/components.hpp>
#include <solanaceae/ngc_ft1/ngcft1_file_kind.hpp>
#include <vector>
#include <cassert>
namespace Systems {
void re_announce(
ObjectRegistry& os_reg,
Contact3Registry& cr,
NGCEXTEventProvider& neep,
const float delta
) {
std::vector<Object> to_remove;
os_reg.view<Components::ReAnnounceTimer>().each([&os_reg, &cr, &neep, &to_remove, delta](Object ov, Components::ReAnnounceTimer& rat) {
ObjectHandle o{os_reg, ov};
// TODO: pause
//// if paused -> remove
//if (o.all_of<Message::Components::Transfer::TagPaused>()) {
// to_remove.push_back(ov);
// return;
//}
// if not downloading or info incomplete -> remove
if (!o.all_of<Components::FT1ChunkSHA1Cache, Components::FT1InfoSHA1Hash, Components::AnnounceTargets>()) {
to_remove.push_back(ov);
assert(false && "transfer in broken state");
return;
}
if (o.all_of<ObjComp::F::TagLocalHaveAll>()) {
// transfer done, we stop announcing
to_remove.push_back(ov);
return;
}
// update all timers
rat.timer -= delta;
// send announces
if (rat.timer <= 0.f) {
rat.reset(); // exponential back-off
std::vector<uint8_t> announce_id;
const uint32_t file_kind = static_cast<uint32_t>(NGCFT1_file_kind::HASH_SHA1_INFO);
for (size_t i = 0; i < sizeof(file_kind); i++) {
announce_id.push_back((file_kind>>(i*8)) & 0xff);
}
assert(o.all_of<Components::FT1InfoSHA1Hash>());
const auto& info_hash = o.get<Components::FT1InfoSHA1Hash>().hash;
announce_id.insert(announce_id.cend(), info_hash.cbegin(), info_hash.cend());
for (const auto cv : o.get<Components::AnnounceTargets>().targets) {
if (cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(cv)) {
// private ?
const auto [group_number, peer_number] = cr.get<Contact::Components::ToxGroupPeerEphemeral>(cv);
neep.send_pc1_announce(group_number, peer_number, announce_id.data(), announce_id.size());
} else if (cr.all_of<Contact::Components::ToxGroupEphemeral>(cv)) {
// public
const auto group_number = cr.get<Contact::Components::ToxGroupEphemeral>(cv).group_number;
neep.send_all_pc1_announce(group_number, announce_id.data(), announce_id.size());
} else {
assert(false && "we dont know how to announce to this target");
}
}
}
});
for (const auto ov : to_remove) {
os_reg.remove<Components::ReAnnounceTimer>(ov);
// we keep the annouce target list around (if it exists)
// TODO: should we make the target list more generic?
}
// TODO: how to handle unpause?
}
} // Systems