commit de8adbd2b77c9ddb26669d4a29a3c6cc05ee2894 Author: Green Sky Date: Sat Apr 8 00:13:28 2023 +0200 first core commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..a35f54d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.9 FATAL_ERROR) + +project(solanaceae) + +add_library(solanaceae_core + ./solanaceae/core/utils.hpp + ./solanaceae/core/utils.cpp + + ./solanaceae/core/tox_interface.hpp + ./solanaceae/core/tox_interface.cpp + ./solanaceae/core/tox_event_interface.hpp + + ./solanaceae/core/tox_default_impl.hpp + ./solanaceae/core/tox_default_impl.cpp + ./solanaceae/core/tox_event_provider_base.hpp + ./solanaceae/core/tox_event_provider_base.cpp + + ./solanaceae/core/tox_event_logger.hpp + ./solanaceae/core/tox_event_logger.cpp +) + +target_include_directories(solanaceae_core PUBLIC .) +target_compile_features(solanaceae_core PUBLIC cxx_std_17) +target_link_libraries(solanaceae_core PUBLIC + toxcore +) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2780797 --- /dev/null +++ b/LICENSE @@ -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. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..eb8a5e3 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +`plant !` + +### requires ngc events [rp](https://github.com/TokTok/c-toxcore/pull/2378) + diff --git a/solanaceae/core/tox_default_impl.cpp b/solanaceae/core/tox_default_impl.cpp new file mode 100644 index 0000000..7c6e146 --- /dev/null +++ b/solanaceae/core/tox_default_impl.cpp @@ -0,0 +1,325 @@ +#include "./tox_default_impl.hpp" + +Tox_Connection ToxDefaultImpl::toxSelfGetConnectionStatus(void) { + return tox_self_get_connection_status(_tox); +} + +uint32_t ToxDefaultImpl::toxIterationInterval(void) { + return tox_iteration_interval(_tox); +} + +std::vector ToxDefaultImpl::toxSelfGetAddress(void) { + std::vector self_addr{}; + self_addr.resize(TOX_ADDRESS_SIZE); + tox_self_get_address(_tox, self_addr.data()); + return self_addr; +} + +void ToxDefaultImpl::toxSelfSetNospam(uint32_t nospam) { + tox_self_set_nospam(_tox, nospam); +} + +uint32_t ToxDefaultImpl::toxSelfGetNospam(void) { + return tox_self_get_nospam(_tox); +} + +std::vector ToxDefaultImpl::toxSelfGetPublicKey(void) { + std::vector self_pub{}; + self_pub.resize(TOX_PUBLIC_KEY_SIZE); + tox_self_get_public_key(_tox, self_pub.data()); + return self_pub; +} + +Tox_Err_Set_Info ToxDefaultImpl::toxSelfSetName(std::string_view name) { + Tox_Err_Set_Info err = TOX_ERR_SET_INFO_OK; + tox_self_set_name(_tox, reinterpret_cast(name.data()), name.size(), &err); + return err; +} + +std::string ToxDefaultImpl::toxSelfGetName(void) { + std::string name; + name.resize(tox_self_get_name_size(_tox)); + tox_self_get_name(_tox, reinterpret_cast(name.data())); + return name; +} + +Tox_Err_Set_Info ToxDefaultImpl::toxSelfSetStatusMessage(std::string_view status_message) { + Tox_Err_Set_Info err = TOX_ERR_SET_INFO_OK; + tox_self_set_status_message(_tox, reinterpret_cast(status_message.data()), status_message.size(), &err); + return err; +} + +std::string ToxDefaultImpl::toxSelfGetStatusMessage(void) { + std::string status; + status.resize(tox_self_get_status_message_size(_tox)); + tox_self_get_status_message(_tox, reinterpret_cast(status.data())); + return status; +} + +void ToxDefaultImpl::toxSelfSetStatus(Tox_User_Status status) { + tox_self_set_status(_tox, status); +} + +Tox_User_Status ToxDefaultImpl::toxSelfGetStatus(void) { + return tox_self_get_status(_tox); +} + +std::tuple, Tox_Err_Friend_Add> ToxDefaultImpl::toxFriendAdd(const std::vector& address, std::string_view message) { + // TODO: check size + Tox_Err_Friend_Add err = TOX_ERR_FRIEND_ADD_OK; + auto res = tox_friend_add(_tox, address.data(), reinterpret_cast(message.data()), message.size(), &err); + if (err == TOX_ERR_FRIEND_ADD_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +std::tuple, Tox_Err_Friend_Add> ToxDefaultImpl::toxFriendAddNorequest(const std::vector& public_key) { + // TODO: check size + Tox_Err_Friend_Add err = TOX_ERR_FRIEND_ADD_OK; + auto res = tox_friend_add_norequest(_tox, public_key.data(), &err); + if (err == TOX_ERR_FRIEND_ADD_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +Tox_Err_Friend_Delete ToxDefaultImpl::toxFriendDelete(uint32_t friend_number) { + Tox_Err_Friend_Delete err = TOX_ERR_FRIEND_DELETE_OK; + tox_friend_delete(_tox, friend_number, &err); + return err; +} + +std::tuple>, Tox_Err_Friend_Get_Public_Key> ToxDefaultImpl::toxFriendGetPublicKey(uint32_t friend_number) { + std::vector pub(TOX_PUBLIC_KEY_SIZE); + Tox_Err_Friend_Get_Public_Key err = TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK; + tox_friend_get_public_key(_tox, friend_number, pub.data(), &err); + if (err == TOX_ERR_FRIEND_GET_PUBLIC_KEY_OK) { + return {pub, err}; + } else { + return {std::nullopt, err}; + } +} + +std::tuple, Tox_Err_Friend_Send_Message> ToxDefaultImpl::toxFriendSendMessage(uint32_t friend_number, Tox_Message_Type type, std::string_view message) { + Tox_Err_Friend_Send_Message err = TOX_ERR_FRIEND_SEND_MESSAGE_OK; + auto res = tox_friend_send_message(_tox, friend_number, type, reinterpret_cast(message.data()), message.size(), &err); + if (err == TOX_ERR_FRIEND_SEND_MESSAGE_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +Tox_Err_Conference_Send_Message ToxDefaultImpl::toxConferenceSendMessage(uint32_t conference_number, Tox_Message_Type type, std::string_view message) { + Tox_Err_Conference_Send_Message err = TOX_ERR_CONFERENCE_SEND_MESSAGE_OK; + tox_conference_send_message(_tox, conference_number, type, reinterpret_cast(message.data()), message.size(), &err); + return err; +} + +Tox_Err_Friend_Custom_Packet ToxDefaultImpl::toxFriendSendLossyPacket(uint32_t friend_number, const std::vector& data) { + Tox_Err_Friend_Custom_Packet err = TOX_ERR_FRIEND_CUSTOM_PACKET_OK; + tox_friend_send_lossy_packet(_tox, friend_number, data.data(), data.size(), &err); + return err; +} + +Tox_Err_Friend_Custom_Packet ToxDefaultImpl::toxFriendSendLosslessPacket(uint32_t friend_number, const std::vector& data) { + Tox_Err_Friend_Custom_Packet err = TOX_ERR_FRIEND_CUSTOM_PACKET_OK; + tox_friend_send_lossless_packet(_tox, friend_number, data.data(), data.size(), &err); + return err; +} + +std::tuple, Tox_Err_Group_New> ToxDefaultImpl::toxGroupNew(Tox_Group_Privacy_State privacy_state, std::string_view group_name, std::string_view name) { + Tox_Err_Group_New err = TOX_ERR_GROUP_NEW_OK; + auto res = tox_group_new(_tox, privacy_state, reinterpret_cast(group_name.data()), group_name.size(), reinterpret_cast(name.data()), name.size(), &err); + if (err == TOX_ERR_GROUP_NEW_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +std::tuple, Tox_Err_Group_Join> ToxDefaultImpl::toxGroupJoin(const std::vector& chat_id, std::string_view name, std::string_view password) { + Tox_Err_Group_Join err = TOX_ERR_GROUP_JOIN_OK; + // TODO: check size + auto res = tox_group_join(_tox, chat_id.data(), reinterpret_cast(name.data()), name.size(), reinterpret_cast(password.data()), password.size(), &err); + if (err == TOX_ERR_GROUP_JOIN_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +std::optional ToxDefaultImpl::toxGroupIsConnected(uint32_t group_number) { + Tox_Err_Group_Is_Connected err = TOX_ERR_GROUP_IS_CONNECTED_OK; + auto res = tox_group_is_connected(_tox, group_number, &err); + if (err == TOX_ERR_GROUP_IS_CONNECTED_OK) { + return res; + } else { + return std::nullopt; + } +} + +Tox_Err_Group_Reconnect ToxDefaultImpl::toxGroupReconnect(uint32_t group_number) { + Tox_Err_Group_Reconnect err = TOX_ERR_GROUP_RECONNECT_OK; + tox_group_reconnect(_tox, group_number, &err); + return err; +} + +Tox_Err_Group_Leave ToxDefaultImpl::toxGroupLeave(uint32_t group_number, std::string_view part_message) { + Tox_Err_Group_Leave err = TOX_ERR_GROUP_LEAVE_OK; + tox_group_leave(_tox, group_number, reinterpret_cast(part_message.data()), part_message.size(), &err); + return err; +} + +std::optional ToxDefaultImpl::toxGroupSelfGetName(uint32_t group_number) { + std::string name; + + Tox_Err_Group_Self_Query err = TOX_ERR_GROUP_SELF_QUERY_OK; + const auto size = tox_group_self_get_name_size(_tox, group_number, &err); + if (err != TOX_ERR_GROUP_SELF_QUERY_OK) { + return std::nullopt; + } + + name.resize(size); + tox_group_self_get_name(_tox, group_number, reinterpret_cast(name.data()), &err); + + if (err == TOX_ERR_GROUP_SELF_QUERY_OK) { + return name; + } else { + return std::nullopt; + } +} + +std::tuple, Tox_Err_Group_Peer_Query> ToxDefaultImpl::toxGroupPeerGetName(uint32_t group_number, uint32_t peer_id) { + std::string name; + + Tox_Err_Group_Peer_Query err = TOX_ERR_GROUP_PEER_QUERY_OK; + const auto size = tox_group_peer_get_name_size(_tox, group_number, peer_id, &err); + if (err != TOX_ERR_GROUP_PEER_QUERY_OK) { + return {std::nullopt, err}; + } + + name.resize(size); + tox_group_peer_get_name(_tox, group_number, peer_id, reinterpret_cast(name.data()), &err); + + if (err == TOX_ERR_GROUP_PEER_QUERY_OK) { + return {name, err}; + } else { + return {std::nullopt, err}; + } +} + +std::tuple, Tox_Err_Group_Peer_Query> ToxDefaultImpl::toxGroupPeerGetConnectionStatus(uint32_t group_number, uint32_t peer_id) { + Tox_Err_Group_Peer_Query err = TOX_ERR_GROUP_PEER_QUERY_OK; + auto res = tox_group_peer_get_connection_status(_tox, group_number, peer_id, &err); + if (err == TOX_ERR_GROUP_PEER_QUERY_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + +Tox_Err_Group_Topic_Set ToxDefaultImpl::toxGroupSetTopic(uint32_t group_number, std::string_view topic) { + Tox_Err_Group_Topic_Set err = TOX_ERR_GROUP_TOPIC_SET_OK; + tox_group_set_topic(_tox, group_number, reinterpret_cast(topic.data()), topic.size(), &err); + return err; +} + +std::optional ToxDefaultImpl::toxGroupGetTopic(uint32_t group_number) { + std::string topic; + + Tox_Err_Group_State_Queries err = TOX_ERR_GROUP_STATE_QUERIES_OK; + const auto size = tox_group_get_topic_size(_tox, group_number, &err); + if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { + return std::nullopt; + } + + topic.resize(size); + tox_group_get_topic(_tox, group_number, reinterpret_cast(topic.data()), &err); + if (err == TOX_ERR_GROUP_STATE_QUERIES_OK) { + return topic; + } else { + return std::nullopt; + } +} + +std::optional ToxDefaultImpl::toxGroupGetName(uint32_t group_number) { + std::string name; + + Tox_Err_Group_State_Queries err = TOX_ERR_GROUP_STATE_QUERIES_OK; + const auto size = tox_group_get_name_size(_tox, group_number, &err); + if (err != TOX_ERR_GROUP_STATE_QUERIES_OK) { + return std::nullopt; + } + + name.resize(size); + tox_group_get_name(_tox, group_number, reinterpret_cast(name.data()), &err); + + if (err == TOX_ERR_GROUP_STATE_QUERIES_OK) { + return name; + } else { + return std::nullopt; + } +} + +std::optional> ToxDefaultImpl::toxGroupGetChatId(uint32_t group_number) { + std::vector chat_id{}; + chat_id.resize(TOX_GROUP_CHAT_ID_SIZE); + + Tox_Err_Group_State_Queries err = TOX_ERR_GROUP_STATE_QUERIES_OK; + tox_group_get_chat_id(_tox, group_number, chat_id.data(), &err); + if (err == TOX_ERR_GROUP_STATE_QUERIES_OK) { + return chat_id; + } else { + return std::nullopt; + } +} + +std::tuple, Tox_Err_Group_Send_Message> ToxDefaultImpl::toxGroupSendMessage(uint32_t group_number, Tox_Message_Type type, std::string_view message) { + Tox_Err_Group_Send_Message err = TOX_ERR_GROUP_SEND_MESSAGE_OK; + uint32_t message_id = 0; + tox_group_send_message(_tox, group_number, type, reinterpret_cast(message.data()), message.size(), &message_id, &err); + if (err == TOX_ERR_GROUP_SEND_MESSAGE_OK) { + return {message_id, err}; + } else { + return {std::nullopt, err}; + } +} + +Tox_Err_Group_Send_Private_Message ToxDefaultImpl::toxGroupSendPrivateMessage(uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, std::string_view message) { + Tox_Err_Group_Send_Private_Message err = TOX_ERR_GROUP_SEND_PRIVATE_MESSAGE_OK; + tox_group_send_private_message(_tox, group_number, peer_id, type, reinterpret_cast(message.data()), message.size(), &err); + return err; +} + +Tox_Err_Group_Send_Custom_Packet ToxDefaultImpl::toxGroupSendCustomPacket(uint32_t group_number, bool lossless, const std::vector& data) { + Tox_Err_Group_Send_Custom_Packet err = TOX_ERR_GROUP_SEND_CUSTOM_PACKET_OK; + tox_group_send_custom_packet(_tox, group_number, lossless, data.data(), data.size(), &err); + return err; +} + +Tox_Err_Group_Send_Custom_Private_Packet ToxDefaultImpl::toxGroupSendCustomPrivatePacket(uint32_t group_number, uint32_t peer_id, bool lossless, const std::vector& data) { + Tox_Err_Group_Send_Custom_Private_Packet err = TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK; + tox_group_send_custom_private_packet(_tox, group_number, peer_id, lossless, data.data(), data.size(), &err); + return err; +} + +Tox_Err_Group_Invite_Friend ToxDefaultImpl::toxGroupInviteFriend(uint32_t group_number, uint32_t friend_number) { + Tox_Err_Group_Invite_Friend err = TOX_ERR_GROUP_INVITE_FRIEND_OK; + tox_group_invite_friend(_tox, group_number, friend_number, &err); + return err; +} + +std::tuple, Tox_Err_Group_Invite_Accept> ToxDefaultImpl::toxGroupInviteAccept(uint32_t friend_number, const std::vector& invite_data, std::string_view name, std::string_view password) { + Tox_Err_Group_Invite_Accept err = TOX_ERR_GROUP_INVITE_ACCEPT_OK; + auto res = tox_group_invite_accept(_tox, friend_number, invite_data.data(), invite_data.size(), reinterpret_cast(name.data()), name.size(), reinterpret_cast(password.data()), password.size(), &err); + if (err == TOX_ERR_GROUP_INVITE_ACCEPT_OK) { + return {res, err}; + } else { + return {std::nullopt, err}; + } +} + diff --git a/solanaceae/core/tox_default_impl.hpp b/solanaceae/core/tox_default_impl.hpp new file mode 100644 index 0000000..e2e0e8e --- /dev/null +++ b/solanaceae/core/tox_default_impl.hpp @@ -0,0 +1,104 @@ +#pragma once + +#include "./tox_interface.hpp" + +struct ToxDefaultImpl : public ToxI { + Tox* _tox = nullptr; + + virtual ~ToxDefaultImpl(void) {} + + Tox_Connection toxSelfGetConnectionStatus(void) override; + uint32_t toxIterationInterval(void) override; + + std::vector toxSelfGetAddress(void) override; + + void toxSelfSetNospam(uint32_t nospam) override; + uint32_t toxSelfGetNospam(void) override; + + std::vector toxSelfGetPublicKey(void) override; + //virtual void toxSelfGetSecretKey(const Tox *tox, uint8_t *secret_key); + + Tox_Err_Set_Info toxSelfSetName(std::string_view name) override; + std::string toxSelfGetName(void) override; + + Tox_Err_Set_Info toxSelfSetStatusMessage(std::string_view status_message) override; + std::string toxSelfGetStatusMessage(void) override; + + void toxSelfSetStatus(Tox_User_Status status) override; + Tox_User_Status toxSelfGetStatus(void) override; + + std::tuple, Tox_Err_Friend_Add> toxFriendAdd(const std::vector& address, std::string_view message) override; + std::tuple, Tox_Err_Friend_Add> toxFriendAddNorequest(const std::vector& public_key) override; + Tox_Err_Friend_Delete toxFriendDelete(uint32_t friend_number) override; + std::tuple>, Tox_Err_Friend_Get_Public_Key> toxFriendGetPublicKey(uint32_t friend_number) override; + + std::tuple, Tox_Err_Friend_Send_Message> toxFriendSendMessage(uint32_t friend_number, Tox_Message_Type type, std::string_view message) override; + + // files + // conferece + Tox_Err_Conference_Send_Message toxConferenceSendMessage(uint32_t conference_number, Tox_Message_Type type, std::string_view message) override; + + Tox_Err_Friend_Custom_Packet toxFriendSendLossyPacket(uint32_t friend_number, const std::vector& data) override; + Tox_Err_Friend_Custom_Packet toxFriendSendLosslessPacket(uint32_t friend_number, const std::vector& data) override; + + // dht + // udp + // tcp + + // group + + std::tuple, Tox_Err_Group_New> toxGroupNew(Tox_Group_Privacy_State privacy_state, std::string_view group_name, std::string_view name) override; + std::tuple, Tox_Err_Group_Join> toxGroupJoin(const std::vector& chat_id, std::string_view name, std::string_view password) override; + std::optional toxGroupIsConnected(uint32_t group_number) override; + //virtual Tox_Err_Group_Disconnect toxGroupDisconnect(uint32_t group_number) = 0; + Tox_Err_Group_Reconnect toxGroupReconnect(uint32_t group_number) override; + Tox_Err_Group_Leave toxGroupLeave(uint32_t group_number, std::string_view part_message) override; + + //virtual Tox_Err_Group_Self_Name_Set toxGroupSelfSetName(uint32_t group_number, std::string_view name) = 0; + std::optional toxGroupSelfGetName(uint32_t group_number) override; + //virtual Tox_Err_Group_Self_Status_Set toxGroupSelfSetStatus(uint32_t group_number, Tox_User_Status status) = 0; + //virtual Tox_User_Status toxGroupSelfGetStatus(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual Tox_Group_Role toxGroupSelfGetRole(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual uint32_t toxGroupSelfGetPeerId(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual std::vector toxGroupSelfGetPublicKey(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + + std::tuple, Tox_Err_Group_Peer_Query> toxGroupPeerGetName(uint32_t group_number, uint32_t peer_id) override; + //virtual Tox_User_Status toxGroupPeerGetStatus(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + //virtual Tox_Group_Role toxGroupPeerGetRole(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + std::tuple, Tox_Err_Group_Peer_Query> toxGroupPeerGetConnectionStatus(uint32_t group_number, uint32_t peer_id) override; + //virtual std::vector toxGroupPeerGetPublicKey(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + + Tox_Err_Group_Topic_Set toxGroupSetTopic(uint32_t group_number, std::string_view topic) override; + std::optional toxGroupGetTopic(uint32_t group_number) override; + + std::optional toxGroupGetName(uint32_t group_number) override; + std::optional> toxGroupGetChatId(uint32_t group_number) override; + // TODO: str + + //virtual uint32_t toxGroupGetNumberGroups(void) = 0; + + //virtual Tox_Group_Privacy_State toxGroupGetPrivacyState(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual Tox_Group_Voice_State toxGroupGetVoiceState(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual Tox_Group_Topic_Lock toxGroupGetTopicLock(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual uint16_t toxGroupGetPeerLimit(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual std::string toxGroupGetPassword(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + + std::tuple, Tox_Err_Group_Send_Message> toxGroupSendMessage(uint32_t group_number, Tox_Message_Type type, std::string_view message) override; + Tox_Err_Group_Send_Private_Message toxGroupSendPrivateMessage(uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, std::string_view message) override; + + Tox_Err_Group_Send_Custom_Packet toxGroupSendCustomPacket(uint32_t group_number, bool lossless, const std::vector& data) override; + Tox_Err_Group_Send_Custom_Private_Packet toxGroupSendCustomPrivatePacket(uint32_t group_number, uint32_t peer_id, bool lossless, const std::vector& data) override; + + Tox_Err_Group_Invite_Friend toxGroupInviteFriend(uint32_t group_number, uint32_t friend_number) override; + std::tuple, Tox_Err_Group_Invite_Accept> toxGroupInviteAccept(uint32_t friend_number, const std::vector& invite_data, std::string_view name, std::string_view password) override; + //virtual Tox_Err_Group_Founder_Set_Password toxGroupFounderSetPassword(uint32_t group_number, std::string_view password) = 0; + //virtual Tox_Err_Group_Founder_Set_Topic_Lock toxGroupFounderSetTopicLock(uint32_t group_number, Tox_Group_Topic_Lock topic_lock) = 0; + //virtual Tox_Err_Group_Founder_Set_Voice_State toxGroupFounderSetVoiceState(uint32_t group_number, Tox_Group_Voice_State voice_state) = 0; + //virtual Tox_Err_Group_Founder_Set_Privacy_State toxGroupFounderSetPrivacyState(uint32_t group_number, Tox_Group_Privacy_State privacy_state) = 0; + //virtual Tox_Err_Group_Founder_Set_Peer_Limit toxGroupFounderSetPeerLimit(uint32_t group_number, uint16_t max_peers) = 0; + //virtual Tox_Err_Group_Set_Ignore toxGroupSetIgnore(uint32_t group_number, uint32_t peer_id, bool ignore) = 0; + //virtual Tox_Err_Group_Mod_Set_Role toxGroupModSetRole(uint32_t group_number, uint32_t peer_id, Tox_Group_Role role) = 0; + //virtual Tox_Err_Group_Mod_Kick_Peer toxGroupModKickPeer(uint32_t group_number, uint32_t peer_id) = 0; + +}; + diff --git a/solanaceae/core/tox_event_interface.hpp b/solanaceae/core/tox_event_interface.hpp new file mode 100644 index 0000000..ffd2a4b --- /dev/null +++ b/solanaceae/core/tox_event_interface.hpp @@ -0,0 +1,177 @@ +#pragma once + +#include + +#include + +// defines the full event interface for tox event subscription +struct ToxEventI { + virtual ~ToxEventI(void) {} + +#define VIRT_EVENT(x) virtual bool onToxEvent(const x*) { return false; } + + // return true if the event is handled and should not be given down the chain + + VIRT_EVENT(Tox_Event_Conference_Connected) + VIRT_EVENT(Tox_Event_Conference_Invite) + VIRT_EVENT(Tox_Event_Conference_Message) + VIRT_EVENT(Tox_Event_Conference_Peer_List_Changed) + VIRT_EVENT(Tox_Event_Conference_Peer_Name) + VIRT_EVENT(Tox_Event_Conference_Title) + + VIRT_EVENT(Tox_Event_File_Chunk_Request) + VIRT_EVENT(Tox_Event_File_Recv) + VIRT_EVENT(Tox_Event_File_Recv_Chunk) + VIRT_EVENT(Tox_Event_File_Recv_Control) + + VIRT_EVENT(Tox_Event_Friend_Connection_Status) + VIRT_EVENT(Tox_Event_Friend_Lossless_Packet) + VIRT_EVENT(Tox_Event_Friend_Lossy_Packet) + VIRT_EVENT(Tox_Event_Friend_Message) + VIRT_EVENT(Tox_Event_Friend_Name) + VIRT_EVENT(Tox_Event_Friend_Read_Receipt) + VIRT_EVENT(Tox_Event_Friend_Request) + VIRT_EVENT(Tox_Event_Friend_Status) + VIRT_EVENT(Tox_Event_Friend_Status_Message) + VIRT_EVENT(Tox_Event_Friend_Typing) + + VIRT_EVENT(Tox_Event_Self_Connection_Status) + + VIRT_EVENT(Tox_Event_Group_Peer_Name) + VIRT_EVENT(Tox_Event_Group_Peer_Status) + VIRT_EVENT(Tox_Event_Group_Topic) + VIRT_EVENT(Tox_Event_Group_Privacy_State) + VIRT_EVENT(Tox_Event_Group_Voice_State) + VIRT_EVENT(Tox_Event_Group_Topic_Lock) + VIRT_EVENT(Tox_Event_Group_Peer_Limit) + VIRT_EVENT(Tox_Event_Group_Password) + VIRT_EVENT(Tox_Event_Group_Message) + VIRT_EVENT(Tox_Event_Group_Private_Message) + VIRT_EVENT(Tox_Event_Group_Custom_Packet) + VIRT_EVENT(Tox_Event_Group_Custom_Private_Packet) + VIRT_EVENT(Tox_Event_Group_Invite) + VIRT_EVENT(Tox_Event_Group_Peer_Join) + VIRT_EVENT(Tox_Event_Group_Peer_Exit) + VIRT_EVENT(Tox_Event_Group_Self_Join) + VIRT_EVENT(Tox_Event_Group_Join_Fail) + VIRT_EVENT(Tox_Event_Group_Moderation) + +#undef VIRT_EVENT +}; + +// defines the interface where to subscribe +struct ToxEventProviderI { + // TODO: unsub + virtual void subscribe(ToxEventI* object, const Tox_Event event_type) = 0; +}; + +constexpr Tox_Event tox_event_from_string(const std::string_view str) { +#define CASE_E_TYPE(x) if (str == #x) return Tox_Event::x; + + CASE_E_TYPE(TOX_EVENT_SELF_CONNECTION_STATUS) + + CASE_E_TYPE(TOX_EVENT_FRIEND_REQUEST) + CASE_E_TYPE(TOX_EVENT_FRIEND_CONNECTION_STATUS) + CASE_E_TYPE(TOX_EVENT_FRIEND_LOSSY_PACKET) + CASE_E_TYPE(TOX_EVENT_FRIEND_LOSSLESS_PACKET) + + CASE_E_TYPE(TOX_EVENT_FRIEND_NAME) + CASE_E_TYPE(TOX_EVENT_FRIEND_STATUS) + CASE_E_TYPE(TOX_EVENT_FRIEND_STATUS_MESSAGE) + + CASE_E_TYPE(TOX_EVENT_FRIEND_MESSAGE) + CASE_E_TYPE(TOX_EVENT_FRIEND_READ_RECEIPT) + CASE_E_TYPE(TOX_EVENT_FRIEND_TYPING) + + CASE_E_TYPE(TOX_EVENT_FILE_CHUNK_REQUEST) + CASE_E_TYPE(TOX_EVENT_FILE_RECV) + CASE_E_TYPE(TOX_EVENT_FILE_RECV_CHUNK) + CASE_E_TYPE(TOX_EVENT_FILE_RECV_CONTROL) + + CASE_E_TYPE(TOX_EVENT_CONFERENCE_INVITE) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_CONNECTED) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_PEER_NAME) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_TITLE) + + CASE_E_TYPE(TOX_EVENT_CONFERENCE_MESSAGE) + + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_NAME) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_STATUS) + CASE_E_TYPE(TOX_EVENT_GROUP_TOPIC) + CASE_E_TYPE(TOX_EVENT_GROUP_PRIVACY_STATE) + CASE_E_TYPE(TOX_EVENT_GROUP_VOICE_STATE) + CASE_E_TYPE(TOX_EVENT_GROUP_TOPIC_LOCK) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_LIMIT) + CASE_E_TYPE(TOX_EVENT_GROUP_PASSWORD) + CASE_E_TYPE(TOX_EVENT_GROUP_MESSAGE) + CASE_E_TYPE(TOX_EVENT_GROUP_PRIVATE_MESSAGE) + CASE_E_TYPE(TOX_EVENT_GROUP_CUSTOM_PACKET) + CASE_E_TYPE(TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) + CASE_E_TYPE(TOX_EVENT_GROUP_INVITE) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_JOIN) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_EXIT) + CASE_E_TYPE(TOX_EVENT_GROUP_SELF_JOIN) + CASE_E_TYPE(TOX_EVENT_GROUP_JOIN_FAIL) + CASE_E_TYPE(TOX_EVENT_GROUP_MODERATION) + + return (Tox_Event)-1; // TODO: add invalid event enum? + +#undef CASE_E_TYPE +} + +constexpr std::string_view tox_event_to_string(const Tox_Event e) { +#define CASE_E_TYPE(x) if (e == x) return #x; + + CASE_E_TYPE(TOX_EVENT_SELF_CONNECTION_STATUS) + + CASE_E_TYPE(TOX_EVENT_FRIEND_REQUEST) + CASE_E_TYPE(TOX_EVENT_FRIEND_CONNECTION_STATUS) + CASE_E_TYPE(TOX_EVENT_FRIEND_LOSSY_PACKET) + CASE_E_TYPE(TOX_EVENT_FRIEND_LOSSLESS_PACKET) + + CASE_E_TYPE(TOX_EVENT_FRIEND_NAME) + CASE_E_TYPE(TOX_EVENT_FRIEND_STATUS) + CASE_E_TYPE(TOX_EVENT_FRIEND_STATUS_MESSAGE) + + CASE_E_TYPE(TOX_EVENT_FRIEND_MESSAGE) + CASE_E_TYPE(TOX_EVENT_FRIEND_READ_RECEIPT) + CASE_E_TYPE(TOX_EVENT_FRIEND_TYPING) + + CASE_E_TYPE(TOX_EVENT_FILE_CHUNK_REQUEST) + CASE_E_TYPE(TOX_EVENT_FILE_RECV) + CASE_E_TYPE(TOX_EVENT_FILE_RECV_CHUNK) + CASE_E_TYPE(TOX_EVENT_FILE_RECV_CONTROL) + + CASE_E_TYPE(TOX_EVENT_CONFERENCE_INVITE) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_CONNECTED) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_PEER_NAME) + CASE_E_TYPE(TOX_EVENT_CONFERENCE_TITLE) + + CASE_E_TYPE(TOX_EVENT_CONFERENCE_MESSAGE) + + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_NAME) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_STATUS) + CASE_E_TYPE(TOX_EVENT_GROUP_TOPIC) + CASE_E_TYPE(TOX_EVENT_GROUP_PRIVACY_STATE) + CASE_E_TYPE(TOX_EVENT_GROUP_VOICE_STATE) + CASE_E_TYPE(TOX_EVENT_GROUP_TOPIC_LOCK) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_LIMIT) + CASE_E_TYPE(TOX_EVENT_GROUP_PASSWORD) + CASE_E_TYPE(TOX_EVENT_GROUP_MESSAGE) + CASE_E_TYPE(TOX_EVENT_GROUP_PRIVATE_MESSAGE) + CASE_E_TYPE(TOX_EVENT_GROUP_CUSTOM_PACKET) + CASE_E_TYPE(TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) + CASE_E_TYPE(TOX_EVENT_GROUP_INVITE) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_JOIN) + CASE_E_TYPE(TOX_EVENT_GROUP_PEER_EXIT) + CASE_E_TYPE(TOX_EVENT_GROUP_SELF_JOIN) + CASE_E_TYPE(TOX_EVENT_GROUP_JOIN_FAIL) + CASE_E_TYPE(TOX_EVENT_GROUP_MODERATION) + + return ""; // TODO: add invalid event enum? + +#undef CASE_E_TYPE +} + diff --git a/solanaceae/core/tox_event_logger.cpp b/solanaceae/core/tox_event_logger.cpp new file mode 100644 index 0000000..628dce3 --- /dev/null +++ b/solanaceae/core/tox_event_logger.cpp @@ -0,0 +1,258 @@ +#include "./tox_event_logger.hpp" + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Connected*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_CONNECTED) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Invite*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_INVITE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Message*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_MESSAGE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Peer_List_Changed*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Peer_Name*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_PEER_NAME) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Conference_Title*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_CONFERENCE_TITLE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_File_Chunk_Request*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FILE_CHUNK_REQUEST) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_File_Recv*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FILE_RECV) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_File_Recv_Chunk*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FILE_RECV_CHUNK) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_File_Recv_Control*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FILE_RECV_CONTROL) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Connection_Status*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_CONNECTION_STATUS) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Lossless_Packet*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_LOSSLESS_PACKET) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Lossy_Packet*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_LOSSY_PACKET) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Message*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_MESSAGE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Name*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_NAME) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Read_Receipt*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_READ_RECEIPT) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Request*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_REQUEST) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Status*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_STATUS) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Status_Message*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_STATUS_MESSAGE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Friend_Typing*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_FRIEND_TYPING) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Self_Connection_Status*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_SELF_CONNECTION_STATUS) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Peer_Name*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PEER_NAME) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Peer_Status*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PEER_STATUS) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Topic*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_TOPIC) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Privacy_State*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PRIVACY_STATE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Voice_State*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_VOICE_STATE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Topic_Lock*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_TOPIC_LOCK) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Peer_Limit*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PEER_LIMIT) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Password*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PASSWORD) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Message*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_MESSAGE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Private_Message*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PRIVATE_MESSAGE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Custom_Packet*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_CUSTOM_PACKET) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Custom_Private_Packet*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Invite*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_INVITE) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Peer_Join*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PEER_JOIN) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Peer_Exit* e) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_PEER_EXIT) + << " grp:" << tox_event_group_peer_exit_get_group_number(e) + << " per:" << tox_event_group_peer_exit_get_peer_id(e) + << " xtp:" << tox_event_group_peer_exit_get_exit_type(e) + << " nam:" << std::string_view{reinterpret_cast(tox_event_group_peer_exit_get_name(e)), tox_event_group_peer_exit_get_name_length(e)} + << " prt:" << std::string_view{reinterpret_cast(tox_event_group_peer_exit_get_part_message(e)), tox_event_group_peer_exit_get_part_message_length(e)} + << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Self_Join*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_SELF_JOIN) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Join_Fail*) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_JOIN_FAIL) << "\n"; + return false; +} + +bool ToxEventLogger::onToxEvent(const Tox_Event_Group_Moderation* e) { + _out << "TOX_EVENT: " << tox_event_to_string(TOX_EVENT_GROUP_MODERATION) + << " grp:" << tox_event_group_moderation_get_group_number(e) + << " typ:" << tox_event_group_moderation_get_mod_type(e) + << " src:" << tox_event_group_moderation_get_source_peer_id(e) + << " trg:" << tox_event_group_moderation_get_target_peer_id(e) + << "\n"; + return false; +} + +void ToxEventLogger::subscribeAll(ToxEventProviderI& tep) { + // TODO: loop + max event + tep.subscribe(this, TOX_EVENT_SELF_CONNECTION_STATUS); + + tep.subscribe(this, TOX_EVENT_FRIEND_REQUEST); + tep.subscribe(this, TOX_EVENT_FRIEND_CONNECTION_STATUS); + tep.subscribe(this, TOX_EVENT_FRIEND_LOSSY_PACKET); + tep.subscribe(this, TOX_EVENT_FRIEND_LOSSLESS_PACKET); + + tep.subscribe(this, TOX_EVENT_FRIEND_NAME); + tep.subscribe(this, TOX_EVENT_FRIEND_STATUS); + tep.subscribe(this, TOX_EVENT_FRIEND_STATUS_MESSAGE); + + tep.subscribe(this, TOX_EVENT_FRIEND_MESSAGE); + tep.subscribe(this, TOX_EVENT_FRIEND_READ_RECEIPT); + tep.subscribe(this, TOX_EVENT_FRIEND_TYPING); + + tep.subscribe(this, TOX_EVENT_FILE_CHUNK_REQUEST); + tep.subscribe(this, TOX_EVENT_FILE_RECV); + tep.subscribe(this, TOX_EVENT_FILE_RECV_CHUNK); + tep.subscribe(this, TOX_EVENT_FILE_RECV_CONTROL); + + tep.subscribe(this, TOX_EVENT_CONFERENCE_INVITE); + tep.subscribe(this, TOX_EVENT_CONFERENCE_CONNECTED); + tep.subscribe(this, TOX_EVENT_CONFERENCE_PEER_LIST_CHANGED); + tep.subscribe(this, TOX_EVENT_CONFERENCE_PEER_NAME); + tep.subscribe(this, TOX_EVENT_CONFERENCE_TITLE); + + tep.subscribe(this, TOX_EVENT_CONFERENCE_MESSAGE); + + tep.subscribe(this, TOX_EVENT_GROUP_PEER_NAME); + tep.subscribe(this, TOX_EVENT_GROUP_PEER_STATUS); + tep.subscribe(this, TOX_EVENT_GROUP_TOPIC); + tep.subscribe(this, TOX_EVENT_GROUP_PRIVACY_STATE); + tep.subscribe(this, TOX_EVENT_GROUP_VOICE_STATE); + tep.subscribe(this, TOX_EVENT_GROUP_TOPIC_LOCK); + tep.subscribe(this, TOX_EVENT_GROUP_PEER_LIMIT); + tep.subscribe(this, TOX_EVENT_GROUP_PASSWORD); + tep.subscribe(this, TOX_EVENT_GROUP_MESSAGE); + tep.subscribe(this, TOX_EVENT_GROUP_PRIVATE_MESSAGE); + tep.subscribe(this, TOX_EVENT_GROUP_CUSTOM_PACKET); + tep.subscribe(this, TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET); + tep.subscribe(this, TOX_EVENT_GROUP_INVITE); + tep.subscribe(this, TOX_EVENT_GROUP_PEER_JOIN); + tep.subscribe(this, TOX_EVENT_GROUP_PEER_EXIT); + tep.subscribe(this, TOX_EVENT_GROUP_SELF_JOIN); + tep.subscribe(this, TOX_EVENT_GROUP_JOIN_FAIL); + tep.subscribe(this, TOX_EVENT_GROUP_MODERATION); +} + diff --git a/solanaceae/core/tox_event_logger.hpp b/solanaceae/core/tox_event_logger.hpp new file mode 100644 index 0000000..e199b73 --- /dev/null +++ b/solanaceae/core/tox_event_logger.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include "./tox_event_interface.hpp" + +#include + +struct ToxEventLogger : public ToxEventI { + std::ostream& _out; + + ToxEventLogger(std::ostream& out) : _out(out) {} + ~ToxEventLogger(void) {} + +#define OVER_EVENT(x) bool onToxEvent(const x*) override; + + OVER_EVENT(Tox_Event_Conference_Connected) + OVER_EVENT(Tox_Event_Conference_Invite) + OVER_EVENT(Tox_Event_Conference_Message) + OVER_EVENT(Tox_Event_Conference_Peer_List_Changed) + OVER_EVENT(Tox_Event_Conference_Peer_Name) + OVER_EVENT(Tox_Event_Conference_Title) + + OVER_EVENT(Tox_Event_File_Chunk_Request) + OVER_EVENT(Tox_Event_File_Recv) + OVER_EVENT(Tox_Event_File_Recv_Chunk) + OVER_EVENT(Tox_Event_File_Recv_Control) + + OVER_EVENT(Tox_Event_Friend_Connection_Status) + OVER_EVENT(Tox_Event_Friend_Lossless_Packet) + OVER_EVENT(Tox_Event_Friend_Lossy_Packet) + OVER_EVENT(Tox_Event_Friend_Message) + OVER_EVENT(Tox_Event_Friend_Name) + OVER_EVENT(Tox_Event_Friend_Read_Receipt) + OVER_EVENT(Tox_Event_Friend_Request) + OVER_EVENT(Tox_Event_Friend_Status) + OVER_EVENT(Tox_Event_Friend_Status_Message) + OVER_EVENT(Tox_Event_Friend_Typing) + + OVER_EVENT(Tox_Event_Self_Connection_Status) + + OVER_EVENT(Tox_Event_Group_Peer_Name) + OVER_EVENT(Tox_Event_Group_Peer_Status) + OVER_EVENT(Tox_Event_Group_Topic) + OVER_EVENT(Tox_Event_Group_Privacy_State) + OVER_EVENT(Tox_Event_Group_Voice_State) + OVER_EVENT(Tox_Event_Group_Topic_Lock) + OVER_EVENT(Tox_Event_Group_Peer_Limit) + OVER_EVENT(Tox_Event_Group_Password) + OVER_EVENT(Tox_Event_Group_Message) + OVER_EVENT(Tox_Event_Group_Private_Message) + OVER_EVENT(Tox_Event_Group_Custom_Packet) + OVER_EVENT(Tox_Event_Group_Custom_Private_Packet) + OVER_EVENT(Tox_Event_Group_Invite) + OVER_EVENT(Tox_Event_Group_Peer_Join) + OVER_EVENT(Tox_Event_Group_Peer_Exit) + OVER_EVENT(Tox_Event_Group_Self_Join) + OVER_EVENT(Tox_Event_Group_Join_Fail) + OVER_EVENT(Tox_Event_Group_Moderation) + +#undef OVER_EVENT + + void subscribeAll(ToxEventProviderI& tep); +}; + diff --git a/solanaceae/core/tox_event_provider_base.cpp b/solanaceae/core/tox_event_provider_base.cpp new file mode 100644 index 0000000..c4cacbb --- /dev/null +++ b/solanaceae/core/tox_event_provider_base.cpp @@ -0,0 +1,76 @@ +#include "./tox_event_provider_base.hpp" + +void ToxEventProviderBase::dispatchEvents(const Tox_Events* events) { + if (events == nullptr) { + return; + } + + // forward events to event handlers + + // TODO: make order independent (construct string and lookup event id) +#define HANDLE_EVENT(x) \ + for (size_t i = 0; i < tox_events_get_##x##_size(events); i++) { \ + for (auto* tei : _subscribers.at(event_type_index)) { \ + if (tei->onToxEvent(tox_events_get_##x(events, i))) { \ + break; \ + } \ + } \ + } \ + event_type_index++; + + size_t event_type_index = 0; + + // IMPORTANT: the order defines the type + HANDLE_EVENT(self_connection_status); + + HANDLE_EVENT(friend_request); + HANDLE_EVENT(friend_connection_status); + HANDLE_EVENT(friend_lossy_packet); + HANDLE_EVENT(friend_lossless_packet); + + HANDLE_EVENT(friend_name); + HANDLE_EVENT(friend_status); + HANDLE_EVENT(friend_status_message); + + HANDLE_EVENT(friend_message); + HANDLE_EVENT(friend_read_receipt); + HANDLE_EVENT(friend_typing); + + HANDLE_EVENT(file_chunk_request); + HANDLE_EVENT(file_recv); + HANDLE_EVENT(file_recv_chunk); + HANDLE_EVENT(file_recv_control); + + HANDLE_EVENT(conference_invite); + HANDLE_EVENT(conference_connected); + HANDLE_EVENT(conference_peer_list_changed); + HANDLE_EVENT(conference_peer_name); + HANDLE_EVENT(conference_title); + + HANDLE_EVENT(conference_message); + + HANDLE_EVENT(group_peer_name); + HANDLE_EVENT(group_peer_status); + HANDLE_EVENT(group_topic); + HANDLE_EVENT(group_privacy_state); + HANDLE_EVENT(group_voice_state); + HANDLE_EVENT(group_topic_lock); + HANDLE_EVENT(group_peer_limit); + HANDLE_EVENT(group_password); + HANDLE_EVENT(group_message); + HANDLE_EVENT(group_private_message); + HANDLE_EVENT(group_custom_packet); + HANDLE_EVENT(group_custom_private_packet); + HANDLE_EVENT(group_invite); + HANDLE_EVENT(group_peer_join); + HANDLE_EVENT(group_peer_exit); + HANDLE_EVENT(group_self_join); + HANDLE_EVENT(group_join_fail); + HANDLE_EVENT(group_moderation); +#undef HANDLE_EVENT +} + +void ToxEventProviderBase::subscribe(ToxEventI* object, const Tox_Event event_type) { + _subscribers.at(event_type).push_back(object); +} + diff --git a/solanaceae/core/tox_event_provider_base.hpp b/solanaceae/core/tox_event_provider_base.hpp new file mode 100644 index 0000000..bc41618 --- /dev/null +++ b/solanaceae/core/tox_event_provider_base.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "./tox_event_interface.hpp" + +#include +#include + +// implements common code for tox event dispatching +struct ToxEventProviderBase : public ToxEventProviderI { + protected: + void dispatchEvents(const Tox_Events* events); + + public: // event provider + virtual void subscribe(ToxEventI* object, const Tox_Event event_type) override; + + protected: + std::array, 39> _subscribers; // rn 39 event types +}; + diff --git a/solanaceae/core/tox_interface.cpp b/solanaceae/core/tox_interface.cpp new file mode 100644 index 0000000..9e1d334 --- /dev/null +++ b/solanaceae/core/tox_interface.cpp @@ -0,0 +1,15 @@ +#include "./tox_interface.hpp" + +#include "./utils.hpp" + +std::string ToxI_raw::toxSelfGetAddressStr(void) { + // TODO: cache + return bin2hex(toxSelfGetAddress()); +} + +std::vector ToxI_raw::toxHash(const std::vector& data) { + std::vector hash(TOX_HASH_LENGTH); + tox_hash(hash.data(), data.data(), data.size()); // TODO: return value? + return hash; +} + diff --git a/solanaceae/core/tox_interface.hpp b/solanaceae/core/tox_interface.hpp new file mode 100644 index 0000000..5405407 --- /dev/null +++ b/solanaceae/core/tox_interface.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include + +#include +#include +#include +#include +#include + +// TODO: c++20 span + +// defines the full interface for tox +// HACK: raw +struct ToxI_raw { + virtual ~ToxI_raw(void) {} + + virtual Tox_Connection toxSelfGetConnectionStatus(void) = 0; + virtual uint32_t toxIterationInterval(void) = 0; + + virtual std::vector toxSelfGetAddress(void) = 0; + virtual std::string toxSelfGetAddressStr(void); // has default impl + + virtual void toxSelfSetNospam(uint32_t nospam) = 0; + virtual uint32_t toxSelfGetNospam(void) = 0; + + virtual std::vector toxSelfGetPublicKey(void) = 0; + //virtual void toxSelfGetSecretKey(const Tox *tox, uint8_t *secret_key); + + virtual Tox_Err_Set_Info toxSelfSetName(std::string_view name) = 0; + virtual std::string toxSelfGetName(void) = 0; + + virtual Tox_Err_Set_Info toxSelfSetStatusMessage(std::string_view status_message) = 0; + virtual std::string toxSelfGetStatusMessage(void) = 0; + + virtual void toxSelfSetStatus(Tox_User_Status status) = 0; + virtual Tox_User_Status toxSelfGetStatus(void) = 0; + + virtual std::tuple, Tox_Err_Friend_Add> toxFriendAdd(const std::vector& address, std::string_view message) = 0; + virtual std::tuple, Tox_Err_Friend_Add> toxFriendAddNorequest(const std::vector& public_key) = 0; + virtual Tox_Err_Friend_Delete toxFriendDelete(uint32_t friend_number) = 0; + virtual std::tuple>, Tox_Err_Friend_Get_Public_Key> toxFriendGetPublicKey(uint32_t friend_number) = 0; + + + virtual std::tuple, Tox_Err_Friend_Send_Message> toxFriendSendMessage(uint32_t friend_number, Tox_Message_Type type, std::string_view message) = 0; + + // TODO: array? make it type agnostic? + virtual std::vector toxHash(const std::vector& data); + + // files + + // conferece + virtual Tox_Err_Conference_Send_Message toxConferenceSendMessage(uint32_t conference_number, Tox_Message_Type type, std::string_view message) = 0; + + virtual Tox_Err_Friend_Custom_Packet toxFriendSendLossyPacket(uint32_t friend_number, const std::vector& data) = 0; + virtual Tox_Err_Friend_Custom_Packet toxFriendSendLosslessPacket(uint32_t friend_number, const std::vector& data) = 0; + + // dht + // udp + // tcp + + // group + + virtual std::tuple, Tox_Err_Group_New> toxGroupNew(Tox_Group_Privacy_State privacy_state, std::string_view group_name, std::string_view name) = 0; + virtual std::tuple, Tox_Err_Group_Join> toxGroupJoin(const std::vector& chat_id, std::string_view name, std::string_view password) = 0; + virtual std::optional toxGroupIsConnected(uint32_t group_number) = 0; // only 1 error type, skip + //virtual Tox_Err_Group_Disconnect toxGroupDisconnect(uint32_t group_number) = 0; + virtual Tox_Err_Group_Reconnect toxGroupReconnect(uint32_t group_number) = 0; + virtual Tox_Err_Group_Leave toxGroupLeave(uint32_t group_number, std::string_view part_message) = 0; + + //virtual Tox_Err_Group_Self_Name_Set toxGroupSelfSetName(uint32_t group_number, std::string_view name) = 0; + virtual std::optional toxGroupSelfGetName(uint32_t group_number) = 0; // only 1 error type, skip + //virtual Tox_Err_Group_Self_Status_Set toxGroupSelfSetStatus(uint32_t group_number, Tox_User_Status status) = 0; + //virtual Tox_User_Status toxGroupSelfGetStatus(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual Tox_Group_Role toxGroupSelfGetRole(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual uint32_t toxGroupSelfGetPeerId(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + //virtual std::vector toxGroupSelfGetPublicKey(uint32_t group_number, Tox_Err_Group_Self_Query *error) = 0; + + virtual std::tuple, Tox_Err_Group_Peer_Query> toxGroupPeerGetName(uint32_t group_number, uint32_t peer_id) = 0; + //virtual Tox_User_Status toxGroupPeerGetStatus(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + //virtual Tox_Group_Role toxGroupPeerGetRole(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + virtual std::tuple, Tox_Err_Group_Peer_Query> toxGroupPeerGetConnectionStatus(uint32_t group_number, uint32_t peer_id) = 0; + //virtual std::vector toxGroupPeerGetPublicKey(uint32_t group_number, uint32_t peer_id, Tox_Err_Group_Peer_Query *error) = 0; + + virtual Tox_Err_Group_Topic_Set toxGroupSetTopic(uint32_t group_number, std::string_view topic) = 0; + virtual std::optional toxGroupGetTopic(uint32_t group_number) = 0; // only 1 error type, skip + + virtual std::optional toxGroupGetName(uint32_t group_number) = 0; // only 1 error type, skip + virtual std::optional> toxGroupGetChatId(uint32_t group_number) = 0; // only 1 error type, skip + // TODO: str + + //virtual uint32_t toxGroupGetNumberGroups(void) = 0; + + //virtual Tox_Group_Privacy_State toxGroupGetPrivacyState(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual Tox_Group_Voice_State toxGroupGetVoiceState(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual Tox_Group_Topic_Lock toxGroupGetTopicLock(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual uint16_t toxGroupGetPeerLimit(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + //virtual std::string toxGroupGetPassword(uint32_t group_number, Tox_Err_Group_State_Queries *error) = 0; + + // returns message_id + virtual std::tuple, Tox_Err_Group_Send_Message> toxGroupSendMessage(uint32_t group_number, Tox_Message_Type type, std::string_view message) = 0; + virtual Tox_Err_Group_Send_Private_Message toxGroupSendPrivateMessage(uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, std::string_view message) = 0; + + virtual Tox_Err_Group_Send_Custom_Packet toxGroupSendCustomPacket(uint32_t group_number, bool lossless, const std::vector& data) = 0; + virtual Tox_Err_Group_Send_Custom_Private_Packet toxGroupSendCustomPrivatePacket(uint32_t group_number, uint32_t peer_id, bool lossless, const std::vector& data) = 0; + + virtual Tox_Err_Group_Invite_Friend toxGroupInviteFriend(uint32_t group_number, uint32_t friend_number) = 0; + virtual std::tuple, Tox_Err_Group_Invite_Accept> toxGroupInviteAccept(uint32_t friend_number, const std::vector& invite_data, std::string_view name, std::string_view password) = 0; + //virtual Tox_Err_Group_Founder_Set_Password toxGroupFounderSetPassword(uint32_t group_number, std::string_view password) = 0; + //virtual Tox_Err_Group_Founder_Set_Topic_Lock toxGroupFounderSetTopicLock(uint32_t group_number, Tox_Group_Topic_Lock topic_lock) = 0; + //virtual Tox_Err_Group_Founder_Set_Voice_State toxGroupFounderSetVoiceState(uint32_t group_number, Tox_Group_Voice_State voice_state) = 0; + //virtual Tox_Err_Group_Founder_Set_Privacy_State toxGroupFounderSetPrivacyState(uint32_t group_number, Tox_Group_Privacy_State privacy_state) = 0; + //virtual Tox_Err_Group_Founder_Set_Peer_Limit toxGroupFounderSetPeerLimit(uint32_t group_number, uint16_t max_peers) = 0; + //virtual Tox_Err_Group_Set_Ignore toxGroupSetIgnore(uint32_t group_number, uint32_t peer_id, bool ignore) = 0; + //virtual Tox_Err_Group_Mod_Set_Role toxGroupModSetRole(uint32_t group_number, uint32_t peer_id, Tox_Group_Role role) = 0; + //virtual Tox_Err_Group_Mod_Kick_Peer toxGroupModKickPeer(uint32_t group_number, uint32_t peer_id) = 0; + +}; + +// HACK: work around zppbits inability to pass string_view as parameter ( https://github.com/eyalz800/zpp_bits/issues/107 ) +struct ToxI : public ToxI_raw { + Tox_Err_Set_Info toxSelfSetName_str(const std::string& name) { + return toxSelfSetName(name); + } + + Tox_Err_Set_Info toxSelfSetStatusMessage_str(const std::string& status_message) { + return toxSelfSetStatusMessage(status_message); + } + + std::tuple, Tox_Err_Friend_Add> toxFriendAdd_str(const std::vector& address, const std::string& message) { + return toxFriendAdd(address, message); + } + + std::tuple, Tox_Err_Friend_Send_Message> toxFriendSendMessage_str(uint32_t friend_number, Tox_Message_Type type, const std::string& message) { + return toxFriendSendMessage(friend_number, type, message); + } + + Tox_Err_Conference_Send_Message toxConferenceSendMessage_str(uint32_t conference_number, Tox_Message_Type type, const std::string& message) { + return toxConferenceSendMessage(conference_number, type, message); + } + + std::tuple, Tox_Err_Group_New> toxGroupNew_str(Tox_Group_Privacy_State privacy_state, const std::string& group_name, const std::string& name) { + return toxGroupNew(privacy_state, group_name, name); + } + + std::tuple, Tox_Err_Group_Join> toxGroupJoin_str(const std::vector& chat_id, const std::string& name, const std::string& password) { + return toxGroupJoin(chat_id, name, password); + } + + Tox_Err_Group_Leave toxGroupLeave_str(uint32_t group_number, const std::string& part_message) { + return toxGroupLeave(group_number, part_message); + } + + Tox_Err_Group_Topic_Set toxGroupSetTopic_str(uint32_t group_number, const std::string& topic) { + return toxGroupSetTopic(group_number, topic); + } + + std::tuple, Tox_Err_Group_Send_Message> toxGroupSendMessage_str(uint32_t group_number, Tox_Message_Type type, const std::string& message) { + return toxGroupSendMessage(group_number, type, message); + } + + Tox_Err_Group_Send_Private_Message toxGroupSendPrivateMessage_str(uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const std::string& message) { + return toxGroupSendPrivateMessage(group_number, peer_id, type, message); + } + + std::tuple, Tox_Err_Group_Invite_Accept> toxGroupInviteAccept_str(uint32_t friend_number, const std::vector& invite_data, const std::string& name, const std::string& password) { + return toxGroupInviteAccept(friend_number, invite_data, name, password); + } +}; + diff --git a/solanaceae/core/utils.cpp b/solanaceae/core/utils.cpp new file mode 100644 index 0000000..4aac2d0 --- /dev/null +++ b/solanaceae/core/utils.cpp @@ -0,0 +1,23 @@ +#include "./utils.hpp" + +#include + +std::vector hex2bin(const std::string& str) { + std::vector bin{}; + bin.resize(str.size()/2, 0); + + sodium_hex2bin(bin.data(), bin.size(), str.c_str(), str.length(), nullptr, nullptr, nullptr); + + return bin; +} + +std::string bin2hex(const std::vector& bin) { + std::string str{}; + str.resize(bin.size()*2, '?'); + + // HECK, std is 1 larger than size returns ('\0') + sodium_bin2hex(str.data(), str.size()+1, bin.data(), bin.size()); + + return str; +} + diff --git a/solanaceae/core/utils.hpp b/solanaceae/core/utils.hpp new file mode 100644 index 0000000..21e62cd --- /dev/null +++ b/solanaceae/core/utils.hpp @@ -0,0 +1,8 @@ +#pragma once + +#include +#include + +std::vector hex2bin(const std::string& str); +std::string bin2hex(const std::vector& bin); +