inital commit, add tox_contacts (version 2)
This commit is contained in:
commit
df87cd9c8a
20
CMakeLists.txt
Normal file
20
CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
||||
|
||||
project(solanaceae)
|
||||
|
||||
add_library(solanaceae_tox_contacts
|
||||
./solanaceae/tox_contacts/components.hpp
|
||||
./solanaceae/tox_contacts/components_id.inl
|
||||
|
||||
./solanaceae/tox_contacts/tox_contact_model2.hpp
|
||||
./solanaceae/tox_contacts/tox_contact_model2.cpp
|
||||
)
|
||||
|
||||
target_include_directories(solanaceae_tox_contacts PUBLIC .)
|
||||
target_compile_features(solanaceae_tox_contacts PUBLIC cxx_std_17)
|
||||
target_link_libraries(solanaceae_tox_contacts PUBLIC
|
||||
solanaceae_util
|
||||
solanaceae_contact
|
||||
solanaceae_toxcore
|
||||
)
|
||||
|
24
LICENSE
Normal file
24
LICENSE
Normal file
@ -0,0 +1,24 @@
|
||||
The Code is under the following License, if not stated otherwise:
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Erik Scholz
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
6
README.md
Normal file
6
README.md
Normal file
@ -0,0 +1,6 @@
|
||||
`plant !`
|
||||
|
||||
provides tox contacts and tox messages
|
||||
|
||||
requires solanaceae_toxcore
|
||||
|
58
solanaceae/tox_contacts/components.hpp
Normal file
58
solanaceae/tox_contacts/components.hpp
Normal file
@ -0,0 +1,58 @@
|
||||
#pragma once
|
||||
|
||||
#include <solanaceae/toxcore/tox_key.hpp>
|
||||
|
||||
namespace Contact::Components {
|
||||
|
||||
// ==========
|
||||
// friend
|
||||
// ==========
|
||||
|
||||
struct ToxFriendPersistent {
|
||||
ToxKey key;
|
||||
};
|
||||
|
||||
struct ToxFriendEphemeral {
|
||||
uint32_t friend_number;
|
||||
};
|
||||
|
||||
|
||||
// ==========
|
||||
// TODO: conference (old groups)
|
||||
// ==========
|
||||
|
||||
struct ToxConfPersistent {
|
||||
ToxKey key;
|
||||
};
|
||||
|
||||
struct ToxConfEhpemeral {
|
||||
uint32_t id;
|
||||
};
|
||||
|
||||
|
||||
// ==========
|
||||
// groups (ngc)
|
||||
// ==========
|
||||
|
||||
struct ToxGroupPersistent {
|
||||
ToxKey chat_id;
|
||||
};
|
||||
|
||||
struct ToxGroupEphemeral {
|
||||
uint32_t group_number;
|
||||
};
|
||||
|
||||
struct ToxGroupPeerPersistent {
|
||||
ToxKey chat_id;
|
||||
ToxKey peer_key;
|
||||
};
|
||||
|
||||
struct ToxGroupPeerEphemeral {
|
||||
uint32_t group_number;
|
||||
uint32_t peer_number;
|
||||
};
|
||||
|
||||
} // Contact::Components
|
||||
|
||||
#include "./components_id.inl"
|
||||
|
25
solanaceae/tox_contacts/components_id.inl
Normal file
25
solanaceae/tox_contacts/components_id.inl
Normal file
@ -0,0 +1,25 @@
|
||||
#include "./components.hpp"
|
||||
|
||||
#include <entt/core/type_info.hpp>
|
||||
|
||||
// TODO: move more central
|
||||
#define DEFINE_COMP_ID(x) \
|
||||
template<> \
|
||||
constexpr entt::id_type entt::type_hash<x>::value() noexcept { \
|
||||
using namespace entt::literals; \
|
||||
return #x##_hs; \
|
||||
}
|
||||
|
||||
// cross compiler stable ids
|
||||
|
||||
DEFINE_COMP_ID(Contact::Components::ToxFriendPersistent)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxFriendEphemeral)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxConfPersistent)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxConfEhpemeral)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxGroupPersistent)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxGroupEphemeral)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxGroupPeerPersistent)
|
||||
DEFINE_COMP_ID(Contact::Components::ToxGroupPeerEphemeral)
|
||||
|
||||
#undef DEFINE_COMP_ID
|
||||
|
409
solanaceae/tox_contacts/tox_contact_model2.cpp
Normal file
409
solanaceae/tox_contacts/tox_contact_model2.cpp
Normal file
@ -0,0 +1,409 @@
|
||||
#include "./tox_contact_model2.hpp"
|
||||
|
||||
#include <solanaceae/toxcore/tox_interface.hpp>
|
||||
#include <solanaceae/contact/components.hpp>
|
||||
|
||||
#include "./components.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
#include <iostream>
|
||||
|
||||
ToxContactModel2::ToxContactModel2(Contact3Registry& cr, ToxI& t, ToxEventProviderI& tep) : _cr(cr), _t(t), _tep(tep) {
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_FRIEND_CONNECTION_STATUS);
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_FRIEND_STATUS);
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_FRIEND_NAME);
|
||||
|
||||
// TODO: conf
|
||||
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_GROUP_SELF_JOIN);
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_GROUP_PEER_JOIN);
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_GROUP_PEER_EXIT);
|
||||
_tep.subscribe(this, Tox_Event::TOX_EVENT_GROUP_PEER_NAME);
|
||||
|
||||
|
||||
// add self
|
||||
Contact3 c = entt::null;
|
||||
// TODO: if self exists
|
||||
|
||||
c = _cr.create();
|
||||
_cr.emplace<Contact::Components::ContactModel>(c, this);
|
||||
_cr.emplace<Contact::Components::TagSelfStrong>(c);
|
||||
_cr.emplace<Contact::Components::Name>(c, _t.toxSelfGetName());
|
||||
|
||||
_friend_self = c;
|
||||
|
||||
// fill in contacts
|
||||
for (const uint32_t f_id : _t.toxSelfGetFriendList()) {
|
||||
getContactFriend(f_id);
|
||||
}
|
||||
|
||||
for (const uint32_t g_id : _t.toxGroupGetList()) {
|
||||
getContactGroup(g_id);
|
||||
}
|
||||
}
|
||||
|
||||
Contact3Handle ToxContactModel2::getContactFriend(uint32_t friend_number) {
|
||||
Contact3 c = entt::null;
|
||||
|
||||
// first check contacts with friend id
|
||||
// TODO: lookup table
|
||||
//_cr.view<Contact::Components::ToxFriendEphemeral>().each([&c, friend_number](const Contact3 e, const Contact::Components::ToxFriendEphemeral& f_id) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxFriendEphemeral>()) {
|
||||
if (_cr.get<Contact::Components::ToxFriendEphemeral>(e).friend_number == friend_number) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// else check by pubkey
|
||||
auto f_key_opt = _t.toxFriendGetPublicKey(friend_number);
|
||||
assert(f_key_opt.has_value()); // TODO: handle gracefully?
|
||||
|
||||
const ToxKey& f_key = f_key_opt.value();
|
||||
//_cr.view<Contact::Components::ToxFriendPersistent>().each([&c, &f_key](const Contact3 e, const Contact::Components::ToxFriendPersistent& f_key_comp) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxFriendPersistent>()) {
|
||||
if (f_key == _cr.get<Contact::Components::ToxFriendPersistent>(e).key) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// else, new ent
|
||||
c = _cr.create();
|
||||
|
||||
_cr.emplace<Contact::Components::TagBig>(c);
|
||||
_cr.emplace<Contact::Components::ContactModel>(c, this);
|
||||
_cr.emplace<Contact::Components::ToxFriendEphemeral>(c, friend_number);
|
||||
_cr.emplace<Contact::Components::ToxFriendPersistent>(c, f_key);
|
||||
_cr.emplace<Contact::Components::Self>(c, _friend_self);
|
||||
_cr.emplace<Contact::Components::Name>(c, _t.toxFriendGetName(friend_number).value_or("<unk>"));
|
||||
|
||||
std::cout << "TCM2: created friend contact " << friend_number << "\n";
|
||||
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
Contact3Handle ToxContactModel2::getContactGroup(uint32_t group_number) {
|
||||
Contact3 c = entt::null;
|
||||
|
||||
// first check contacts with group_number
|
||||
// TODO: lookup table
|
||||
//_cr.view<Contact::Components::ToxGroupEphemeral>().each([&c, group_number](const Contact3 e, const Contact::Components::ToxGroupEphemeral& g_e) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxGroupEphemeral>()) {
|
||||
if (_cr.get<Contact::Components::ToxGroupEphemeral>(e).group_number == group_number) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// else check by pubkey
|
||||
auto g_key_opt = _t.toxGroupGetChatId(group_number);
|
||||
assert(g_key_opt.has_value()); // TODO: handle gracefully?
|
||||
|
||||
const ToxKey& g_key = g_key_opt.value();
|
||||
//_cr.view<Contact::Components::ToxGroupPersistent>().each([&c, &g_key](const Contact3 e, const Contact::Components::ToxGroupPersistent& g_key_comp) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxGroupPersistent>()) {
|
||||
if (g_key == _cr.get<Contact::Components::ToxGroupPersistent>(e).chat_id) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// else, new ent
|
||||
c = _cr.create();
|
||||
|
||||
_cr.emplace<Contact::Components::ContactModel>(c, this);
|
||||
_cr.emplace<Contact::Components::TagBig>(c);
|
||||
_cr.emplace<Contact::Components::ParentOf>(c); // start empty
|
||||
_cr.emplace<Contact::Components::ToxGroupEphemeral>(c, group_number);
|
||||
_cr.emplace<Contact::Components::ToxGroupPersistent>(c, g_key);
|
||||
_cr.emplace<Contact::Components::Name>(c, _t.toxGroupGetName(group_number).value_or("<unk>"));
|
||||
_cr.emplace<Contact::Components::ConnectionState>(
|
||||
c,
|
||||
_t.toxGroupIsConnected(group_number).value_or(false)
|
||||
? Contact::Components::ConnectionState::State::cloud
|
||||
: Contact::Components::ConnectionState::State::disconnected
|
||||
);
|
||||
|
||||
auto self_opt = _t.toxGroupSelfGetPeerId(group_number);
|
||||
if (self_opt.has_value()) {
|
||||
_cr.emplace<Contact::Components::Self>(c, getContactGroupPeer(group_number, self_opt.value()));
|
||||
} else {
|
||||
std::cerr << "TCM2 error: getting self for group" << group_number << "!!\n";
|
||||
}
|
||||
|
||||
std::cout << "TCM2: created group contact " << group_number << "\n";
|
||||
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
Contact3Handle ToxContactModel2::getContactGroupPeer(uint32_t group_number, uint32_t peer_number) {
|
||||
Contact3 c = entt::null;
|
||||
|
||||
Contact3Handle group_c = getContactGroup(group_number);
|
||||
|
||||
assert(static_cast<bool>(group_c));
|
||||
|
||||
// first check contacts with peer id
|
||||
// TODO: lookup table
|
||||
//_cr.view<Contact::Components::ToxGroupPeerEphemeral>().each([&c, group_number, peer_number](const Contact3 e, const Contact::Components::ToxGroupPeerEphemeral& p_comp) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxGroupPeerEphemeral>()) {
|
||||
const auto& p_comp = _cr.get<Contact::Components::ToxGroupPeerEphemeral>(e);
|
||||
if (p_comp.group_number == group_number && p_comp.peer_number == peer_number) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
const auto& g_key = group_c.get<Contact::Components::ToxGroupPersistent>().chat_id;
|
||||
|
||||
// else check by key
|
||||
auto [g_p_key_opt, _] = _t.toxGroupPeerGetPublicKey(group_number, peer_number);
|
||||
if (!g_p_key_opt.has_value()) {
|
||||
}
|
||||
//assert(g_p_key_opt.has_value()); // TODO: handle gracefully?
|
||||
if (!g_p_key_opt.has_value()) {
|
||||
// if the key could not be retreived, that means the peer has exited (idk why the earlier search did not work, it should have)
|
||||
// also exit here, to not create, pubkey less <.<
|
||||
std::cerr << "TCM2 error: we did not have offline peer in db, which is worrying\n";
|
||||
return {};
|
||||
}
|
||||
|
||||
const ToxKey& g_p_key = g_p_key_opt.value();
|
||||
//_cr.view<Contact::Components::ToxGroupPeerPersistent>().each([&c, &g_key, &g_p_key](const Contact3 e, const Contact::Components::ToxGroupPeerPersistent& g_p_key_comp) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxGroupPeerPersistent>()) {
|
||||
const auto& g_p_key_comp = _cr.get<Contact::Components::ToxGroupPeerPersistent>(e);
|
||||
if (g_p_key == g_p_key_comp.peer_key && g_key == g_p_key_comp.chat_id) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// else, new ent
|
||||
c = _cr.create();
|
||||
|
||||
_cr.emplace<Contact::Components::Parent>(c, group_c);
|
||||
{ // add sub to parent
|
||||
auto& parent_sub_list = group_c.get_or_emplace<Contact::Components::ParentOf>().subs;
|
||||
if (std::find(parent_sub_list.cbegin(), parent_sub_list.cend(), c) == parent_sub_list.cend()) {
|
||||
parent_sub_list.push_back(c);
|
||||
}
|
||||
}
|
||||
_cr.emplace<Contact::Components::ContactModel>(c, this);
|
||||
_cr.emplace<Contact::Components::ToxGroupPeerEphemeral>(c, group_number, peer_number);
|
||||
_cr.emplace<Contact::Components::ToxGroupPeerPersistent>(c, g_key, g_p_key);
|
||||
const auto name_opt = std::get<0>(_t.toxGroupPeerGetName(group_number, peer_number));
|
||||
if (name_opt.has_value()) {
|
||||
_cr.emplace<Contact::Components::Name>(c, name_opt.value());
|
||||
}
|
||||
|
||||
{ // self
|
||||
// TODO: this is very flaky
|
||||
auto self_number_opt = _t.toxGroupSelfGetPeerId(group_number);
|
||||
if (peer_number == self_number_opt.value()) {
|
||||
_cr.emplace<Contact::Components::TagSelfStrong>(c);
|
||||
} else {
|
||||
_cr.emplace<Contact::Components::Self>(c, getContactGroupPeer(group_number, self_number_opt.value()));
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << "TCM2: created group peer contact " << group_number << " " << peer_number << "\n";
|
||||
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
//Contact3Handle ToxContactModel2::getContactGroupPeer(const ToxKey& group_key, const ToxKey& peer_key) {
|
||||
//return {};
|
||||
//}
|
||||
|
||||
Contact3Handle ToxContactModel2::getContactGroupPeer(uint32_t group_number, const ToxKey& peer_key) {
|
||||
Contact3 c = entt::null;
|
||||
|
||||
Contact3Handle group_c = getContactGroup(group_number);
|
||||
|
||||
assert(static_cast<bool>(group_c));
|
||||
|
||||
const auto& g_key = group_c.get<Contact::Components::ToxGroupPersistent>().chat_id;
|
||||
|
||||
// search by key
|
||||
//_cr.view<Contact::Components::ToxGroupPeerPersistent>().each([&c, &g_key, &peer_key](const Contact3 e, const Contact::Components::ToxGroupPeerPersistent& g_p_key_comp) {
|
||||
for (const auto e : _cr.view<Contact::Components::ToxGroupPeerPersistent>()) {
|
||||
const auto& g_p_key_comp = _cr.get<Contact::Components::ToxGroupPeerPersistent>(e);
|
||||
if (peer_key == g_p_key_comp.peer_key && g_key == g_p_key_comp.chat_id) {
|
||||
c = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_cr.valid(c)) {
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
// TODO: maybe not create contacts via history sync
|
||||
// else, new ent
|
||||
c = _cr.create();
|
||||
|
||||
_cr.emplace<Contact::Components::Parent>(c, group_c);
|
||||
_cr.emplace<Contact::Components::ContactModel>(c, this);
|
||||
//_cr.emplace<Contact::Components::ToxGroupPeerEphemeral>(c, group_number, peer_number);
|
||||
_cr.emplace<Contact::Components::ToxGroupPeerPersistent>(c, g_key, peer_key);
|
||||
//_cr.emplace<Contact::Components::Name>(c, "<unk>");
|
||||
//_cr.emplace<Contact::Components::Name>(c, std::get<0>(_t.toxGroupPeerGetName(group_number, peer_number)).value_or("<unk>"));
|
||||
|
||||
{ // self
|
||||
// TODO: this is very flaky
|
||||
auto self_number_opt = _t.toxGroupSelfGetPeerId(group_number);
|
||||
_cr.emplace<Contact::Components::Self>(c, getContactGroupPeer(group_number, self_number_opt.value()));
|
||||
}
|
||||
|
||||
std::cout << "TCM2: created group peer contact via pubkey " << group_number << "\n";
|
||||
|
||||
return {_cr, c};
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Friend_Connection_Status* e) {
|
||||
const Tox_Connection connection_status = tox_event_friend_connection_status_get_connection_status(e);
|
||||
auto c = getContactFriend(tox_event_friend_connection_status_get_friend_number(e));
|
||||
|
||||
c.emplace_or_replace<Contact::Components::ConnectionState>(
|
||||
(connection_status == TOX_CONNECTION_NONE) ? Contact::Components::ConnectionState::State::disconnected :
|
||||
(connection_status == TOX_CONNECTION_UDP) ? Contact::Components::ConnectionState::State::direct :
|
||||
Contact::Components::ConnectionState::State::cloud
|
||||
);
|
||||
|
||||
if (connection_status == TOX_CONNECTION_NONE) {
|
||||
c.remove<Contact::Components::ToxFriendEphemeral>();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Friend_Status* e) {
|
||||
//tox_event_friend_status_get_status(e);
|
||||
|
||||
//TOX_USER_STATUS_NONE,
|
||||
//TOX_USER_STATUS_AWAY,
|
||||
//TOX_USER_STATUS_BUSY,
|
||||
|
||||
//auto c = getContactFriend(tox_event_friend_status_get_friend_number(e));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Friend_Name* e) {
|
||||
const std::string_view name {
|
||||
reinterpret_cast<const char*>(tox_event_friend_name_get_name(e)),
|
||||
tox_event_friend_name_get_name_length(e)
|
||||
};
|
||||
|
||||
auto c = getContactFriend(tox_event_friend_name_get_friend_number(e));
|
||||
c.emplace_or_replace<Contact::Components::Name>(std::string{name});
|
||||
|
||||
return false; // return true?
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Group_Self_Join* e) {
|
||||
const uint32_t group_number = tox_event_group_self_join_get_group_number(e);
|
||||
if (const auto self_id_opt = _t.toxGroupSelfGetPeerId(group_number); self_id_opt.has_value()) {
|
||||
auto c = getContactGroupPeer(group_number, self_id_opt.value());
|
||||
c.emplace_or_replace<Contact::Components::TagSelfStrong>();
|
||||
c.emplace_or_replace<Contact::Components::ConnectionState>(Contact::Components::ConnectionState::State::direct);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Group_Peer_Join* e) {
|
||||
const uint32_t group_number = tox_event_group_peer_join_get_group_number(e);
|
||||
const uint32_t peer_number = tox_event_group_peer_join_get_peer_id(e);
|
||||
|
||||
auto c = getContactGroupPeer(group_number, peer_number);
|
||||
|
||||
// ensure its set
|
||||
c.emplace_or_replace<Contact::Components::ToxGroupPeerEphemeral>(group_number, peer_number);
|
||||
|
||||
auto [peer_state_opt, _] = _t.toxGroupPeerGetConnectionStatus(group_number, peer_number);
|
||||
c.emplace_or_replace<Contact::Components::ConnectionState>(
|
||||
(peer_state_opt.value_or(TOX_CONNECTION_NONE) == TOX_CONNECTION_NONE) ? Contact::Components::ConnectionState::State::disconnected :
|
||||
(peer_state_opt.value_or(TOX_CONNECTION_NONE) == TOX_CONNECTION_UDP) ? Contact::Components::ConnectionState::State::direct :
|
||||
Contact::Components::ConnectionState::State::cloud
|
||||
);
|
||||
|
||||
// update name
|
||||
const auto name_opt = std::get<0>(_t.toxGroupPeerGetName(group_number, peer_number));
|
||||
if (name_opt.has_value()) {
|
||||
_cr.emplace_or_replace<Contact::Components::Name>(c, name_opt.value());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Group_Peer_Exit* e) {
|
||||
const uint32_t group_number = tox_event_group_peer_exit_get_group_number(e);
|
||||
const uint32_t peer_number = tox_event_group_peer_exit_get_peer_id(e);
|
||||
const auto exit_type = tox_event_group_peer_exit_get_exit_type(e);
|
||||
// set name?
|
||||
// we dont care about the part messae?
|
||||
|
||||
if (exit_type == Tox_Group_Exit_Type::TOX_GROUP_EXIT_TYPE_SELF_DISCONNECTED) {
|
||||
// you disconnected intentionally, or you where kicked
|
||||
// TODO: we need to remove all ToxGroupPeerEphemeral components of that group
|
||||
} else {
|
||||
auto c = getContactGroupPeer(group_number, peer_number);
|
||||
|
||||
if (!static_cast<bool>(c)) {
|
||||
return false; // we dont track this contact ?????
|
||||
}
|
||||
|
||||
c.emplace_or_replace<Contact::Components::ConnectionState>(Contact::Components::ConnectionState::State::disconnected);
|
||||
c.remove<Contact::Components::ToxGroupPeerEphemeral>();
|
||||
|
||||
// they where kicked
|
||||
// exit_type == Tox_Group_Exit_Type::TOX_GROUP_EXIT_TYPE_KICK
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToxContactModel2::onToxEvent(const Tox_Event_Group_Peer_Name* e) {
|
||||
const uint32_t group_number = tox_event_group_peer_name_get_group_number(e);
|
||||
const uint32_t peer_number = tox_event_group_peer_name_get_peer_id(e);
|
||||
|
||||
const std::string_view name {
|
||||
reinterpret_cast<const char*>(tox_event_group_peer_name_get_name(e)),
|
||||
tox_event_group_peer_name_get_name_length(e)
|
||||
};
|
||||
|
||||
auto c = getContactGroupPeer(group_number, peer_number);
|
||||
|
||||
c.emplace_or_replace<Contact::Components::Name>(std::string{name});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
45
solanaceae/tox_contacts/tox_contact_model2.hpp
Normal file
45
solanaceae/tox_contacts/tox_contact_model2.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
||||
#include <solanaceae/contact/contact_model3.hpp>
|
||||
|
||||
#include <solanaceae/toxcore/tox_key.hpp>
|
||||
|
||||
// fwd
|
||||
struct ToxI;
|
||||
|
||||
// tox contact model for ContactModel3I
|
||||
class ToxContactModel2 : public ContactModel3I, public ToxEventI {
|
||||
Contact3Registry& _cr;
|
||||
ToxI& _t;
|
||||
ToxEventProviderI& _tep;
|
||||
|
||||
Contact3 _friend_self;
|
||||
|
||||
public:
|
||||
ToxContactModel2(Contact3Registry& cr, ToxI& t, ToxEventProviderI& tep);
|
||||
virtual ~ToxContactModel2(void) {}
|
||||
|
||||
// TODO: continually fetch group peer connection state, since JF does not want to add cb/event
|
||||
//void iterate(void);
|
||||
|
||||
public: // util for tox code
|
||||
// also creates if non existant
|
||||
Contact3Handle getContactFriend(uint32_t friend_number);
|
||||
|
||||
Contact3Handle getContactGroup(uint32_t group_number);
|
||||
Contact3Handle getContactGroupPeer(uint32_t group_number, uint32_t peer_number);
|
||||
//Contact3Handle getContactGroupPeer(const ToxKey& group_key, const ToxKey& peer_key);
|
||||
Contact3Handle getContactGroupPeer(uint32_t group_number, const ToxKey& peer_key);
|
||||
|
||||
protected: // tox events
|
||||
bool onToxEvent(const Tox_Event_Friend_Connection_Status* e) override;
|
||||
bool onToxEvent(const Tox_Event_Friend_Status* e) override;
|
||||
bool onToxEvent(const Tox_Event_Friend_Name* e) override;
|
||||
|
||||
bool onToxEvent(const Tox_Event_Group_Self_Join* e) override;
|
||||
bool onToxEvent(const Tox_Event_Group_Peer_Join* e) override;
|
||||
bool onToxEvent(const Tox_Event_Group_Peer_Exit* e) override;
|
||||
bool onToxEvent(const Tox_Event_Group_Peer_Name* e) override;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user