diff --git a/CMakeLists.txt b/CMakeLists.txt index f6228e4eb8..6f7e6a50fb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -239,6 +239,24 @@ set(toxcore_SOURCES toxcore/events/friend_status_message.c toxcore/events/friend_typing.c toxcore/events/self_connection_status.c + toxcore/events/group_custom_packet.c + toxcore/events/group_custom_private_packet.c + toxcore/events/group_invite.c + toxcore/events/group_join_fail.c + toxcore/events/group_message.c + toxcore/events/group_moderation.c + toxcore/events/group_password.c + toxcore/events/group_peer_exit.c + toxcore/events/group_peer_join.c + toxcore/events/group_peer_limit.c + toxcore/events/group_peer_name.c + toxcore/events/group_peer_status.c + toxcore/events/group_privacy_state.c + toxcore/events/group_private_message.c + toxcore/events/group_self_join.c + toxcore/events/group_topic.c + toxcore/events/group_topic_lock.c + toxcore/events/group_voice_state.c toxcore/forwarding.c toxcore/forwarding.h toxcore/friend_connection.c diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index c4ec0dc501..b446660cfd 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -62d2c7ab2a14d1f9b00acaf13813b3ea916ccfb2173c9ba95ac82a843a258119 /usr/local/bin/tox-bootstrapd +4f5b47978dc26aed78719526f862a44693f821db12f5ff6d70b338d67fb6f784 /usr/local/bin/tox-bootstrapd diff --git a/other/event_tooling/.gitignore b/other/event_tooling/.gitignore new file mode 100644 index 0000000000..89f9ac04aa --- /dev/null +++ b/other/event_tooling/.gitignore @@ -0,0 +1 @@ +out/ diff --git a/other/event_tooling/generate_event_c.cpp b/other/event_tooling/generate_event_c.cpp new file mode 100644 index 0000000000..c332248095 --- /dev/null +++ b/other/event_tooling/generate_event_c.cpp @@ -0,0 +1,779 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +// Copyright © 2023 The TokTok team. + +// this file can be used to generate event.c files +// requires c++17 + +#include +#include +#include +#include +#include +#include +#include + +std::string str_tolower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::tolower(c); }); + return s; +} + +std::string str_toupper(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::toupper(c); }); + return s; +} + +std::string output_folder = "out"; + +struct EventTypeTrivial { + std::string type; // eg uint32_t + std::string name; // eg friend_number +}; + +struct EventTypeByteRange { + // type is always uint8_t * for data AND uint32_t for length + std::string name_data; // eg data + std::string name_length; // eg data_length + std::string name_length_cb; // eg length // TODO: merge with normal? +}; + +// TODO: EventTypeByteArray + +using EventType = std::variant; + +// helper type for the visitor #4 +template struct overloaded : Ts... { using Ts::operator()...; }; +// explicit deduction guide (not needed as of C++20) +template overloaded(Ts...) -> overloaded; + +std::string bin_pack_name_from_type(const std::string& type) { + if (type == "uint64_t") { + return "bin_pack_u64"; + } else if (type == "uint32_t") { + return "bin_pack_u32"; + } else if (type == "uint16_t") { + return "bin_pack_u16"; + } else if (type == "uint8_t") { + return "bin_pack_u8"; + } else if (type == "bool") { + return "bin_pack_bool"; + // only unpack is special TODO(Green-Sky): should we change that? + //} else if (type == "Tox_User_Status") { + //return "tox_pack_user_status"; + //} else if (type == "Tox_Conference_Type") { + //return "tox_pack_conference_type"; + } else { + //std::cerr << "unknown type " << type << "\n"; + //exit(1); + // assume enum -> u32 + return "bin_pack_u32"; + } +} +std::string bin_unpack_name_from_type(const std::string& type) { + if (type == "uint64_t") { + return "bin_unpack_u64"; + } else if (type == "uint32_t") { + return "bin_unpack_u32"; + } else if (type == "uint16_t") { + return "bin_unpack_u16"; + } else if (type == "uint8_t") { + return "bin_unpack_u8"; + } else if (type == "bool") { + return "bin_unpack_bool"; + } else if (type == "Tox_User_Status") { + return "tox_unpack_user_status"; + } else if (type == "Tox_Conference_Type") { + return "tox_unpack_conference_type"; + } else if (type == "Tox_Message_Type") { + return "tox_unpack_message_type"; + } else if (type == "Tox_File_Control") { + return "tox_unpack_file_control"; + } else if (type == "Tox_Connection") { + return "tox_unpack_connection"; + } else if (type == "Tox_Group_Privacy_State") { + return "tox_unpack_group_privacy_state"; + } else if (type == "Tox_Group_Voice_State") { + return "tox_unpack_group_voice_state"; + } else if (type == "Tox_Group_Topic_Lock") { + return "tox_unpack_group_topic_lock"; + } else if (type == "Tox_Group_Join_Fail") { + return "tox_unpack_group_join_fail"; + } else if (type == "Tox_Group_Mod_Event") { + return "tox_unpack_group_mod_event"; + } else if (type == "Tox_Group_Exit_Type") { + return "tox_unpack_group_exit_type"; + } else { + std::cerr << "unknown type " << type << "\n"; + exit(1); + // assume enum -> u32 + return "bin_unpack_u32"; + } +} + +void generate_event_impl(const std::string& event_name, std::vector event_types) { + const std::string event_name_l = str_tolower(event_name); + std::string file_name = output_folder + "/" + event_name_l + ".c"; + + std::ofstream f(file_name); + if (!f.good()) { + std::cerr << "error opening file to write " << file_name << "\n"; + exit(1); + } + + f << R"(/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +)"; + + // gen struct + f << "struct Tox_Event_" << event_name << " {\n"; + for (const auto& t : event_types) { + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << " " << t.type << " " << t.name << ";\n"; + }, + [&](const EventTypeByteRange& t) { + f << " " << "uint8_t" << " *" << t.name_data << ";\n"; + f << " " << "uint32_t" << " " << t.name_length << ";\n"; + } + }, + t + ); + } + f << "};\n\n"; + + // gen contruct + f << "non_null()\n"; + f << "static void tox_event_" << event_name_l << "_construct(Tox_Event_" << event_name << " *" << event_name_l << ")\n{\n"; + // TODO: initialize all members properly + // TODO: check if _NONE is universal + // str_toupper( + f << " *" << event_name_l << " = (Tox_Event_" << event_name << ") {\n 0\n };\n}\n"; + + // gen destruct + f << "non_null()\n"; + f << "static void tox_event_" << event_name_l << "_destruct(Tox_Event_" << event_name << " *" << event_name_l << ")\n{\n"; + size_t data_count = 0; + for (const auto& t : event_types) { + std::visit( + overloaded{ + [&](const EventTypeTrivial&) {}, + [&](const EventTypeByteRange& t) { + f << " free(" << event_name_l << "->" << t.name_data << ");\n"; + data_count++; + } + }, + t + ); + } + if (data_count == 0) { + f << " return;\n"; + } + f << "}\n\n"; + + // gen setters and getters + for (const auto& t : event_types) { + // setter + f << "non_null()\n"; + f << "static " << (t.index() == 0 ? "void" : "bool") << " tox_event_" << event_name_l << "_set_"; + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << t.name; + }, + [&](const EventTypeByteRange& t) { + f << t.name_data; + } + }, + t + ); + f << "(Tox_Event_" << event_name << " *" << event_name_l << ",\n"; + f << " "; + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << t.type << " " << t.name << ")\n"; + }, + [&](const EventTypeByteRange& t) { + f << "const uint8_t *" << t.name_data << ", uint32_t " << t.name_length << ")\n"; + } + }, + t + ); + f << "{\n assert(" << event_name_l << " != nullptr);\n"; + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << " " << event_name_l << "->" << t.name << " = " << t.name << ";\n"; + }, + [&](const EventTypeByteRange& t) { + f << "\n if (" << event_name_l << "->" << t.name_data << " != nullptr) {\n"; + f << " free(" << event_name_l << "->" << t.name_data << ");\n"; + f << " " << event_name_l << "->" << t.name_data << " = nullptr;\n"; + f << " " << event_name_l << "->" << t.name_length << " = 0;\n"; + f << " }\n\n"; + f << " " << event_name_l << "->" << t.name_data << " = (uint8_t *)malloc(" << t.name_length << ");\n\n"; + f << " if (" << event_name_l << "->" << t.name_data << " == nullptr) {\n"; + f << " return false;\n }\n\n"; + f << " memcpy(" << event_name_l << "->" << t.name_data << ", " << t.name_data << ", " << t.name_length << ");\n"; + f << " " << event_name_l << "->" << t.name_length << " = " << t.name_length << ";\n"; + f << " return true;\n"; + } + }, + t + ); + f << "}\n"; + + // getter + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + //f << "non_null()\n"; // TODO: is this missing in the original? + f << t.type << " tox_event_" << event_name_l << "_get_" << t.name; + f << "(const Tox_Event_" << event_name << " *" << event_name_l << ")\n"; + f << "{\n assert(" << event_name_l << " != nullptr);\n"; + f << " return " << event_name_l << "->" << t.name << ";\n}\n\n"; + }, + [&](const EventTypeByteRange& t) { + //f << "non_null()\n"; // TODO: is this missing in the original? + f << "size_t tox_event_" << event_name_l << "_get_" << t.name_length; + f << "(const Tox_Event_" << event_name << " *" << event_name_l << ")\n"; + f << "{\n assert(" << event_name_l << " != nullptr);\n"; + f << " return " << event_name_l << "->" << t.name_length << ";\n}\n"; + f << "const uint8_t *tox_event_" << event_name_l << "_get_" << t.name_data; + f << "(const Tox_Event_" << event_name << " *" << event_name_l << ")\n"; + f << "{\n assert(" << event_name_l << " != nullptr);\n"; + f << " return " << event_name_l << "->" << t.name_data << ";\n}\n\n"; + } + }, + t + ); + } + + // pack + f << "non_null()\n"; + f << "static bool tox_event_" << event_name_l << "_pack(\n"; + f << " const Tox_Event_" << event_name << " *event, Bin_Pack *bp)\n{\n"; + f << " assert(event != nullptr);\n"; + f << " return bin_pack_array(bp, 2)\n"; + f << " && bin_pack_u32(bp, TOX_EVENT_" << str_toupper(event_name) << ")\n"; + if (event_types.size() > 1) { + f << " && bin_pack_array(bp, " << event_types.size() << ")"; + } + + for (const auto& t : event_types) { + f << "\n && "; + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << bin_pack_name_from_type(t.type); + f << "(bp, event->" << t.name << ")"; + }, + [&](const EventTypeByteRange& t) { + f << "bin_pack_bin(bp, event->" << t.name_data << ", event->" << t.name_length << ")"; + } + }, + t + ); + } + f << ";\n}\n\n"; + + // unpack + f << "non_null()\n"; + f << "static bool tox_event_" << event_name_l << "_unpack(\n"; + f << " Tox_Event_" << event_name << " *event, Bin_Unpack *bu)\n{\n"; + f << " assert(event != nullptr);\n"; + if (event_types.size() > 1) { + f << " if (!bin_unpack_array_fixed(bu, " << event_types.size() << ")) {\n return false;\n }\n\n"; + } + + bool first = true; + for (const auto& t : event_types) { + if (first) { + f << " return "; + } else { + f << "\n && "; + } + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << bin_unpack_name_from_type(t.type); + f << "(bu, &event->" << t.name << ")"; + }, + [&](const EventTypeByteRange& t) { + f << "bin_unpack_bin(bu, &event->" << t.name_data << ", &event->" << t.name_length << ")"; + } + }, + t + ); + first = false; + } + f << ";\n}\n\n"; + + f << R"( +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +)"; + + // add + f << "non_null()\n"; + f << "static Tox_Event_" << event_name << " *tox_events_add_" << event_name_l << "(Tox_Events *events)\n{\n"; + f << " if (events->" << event_name_l << "_size == UINT32_MAX) {\n"; + f << " return nullptr;\n }\n\n"; + f << " if (events->" << event_name_l << "_size == events->" << event_name_l << "_capacity) {\n"; + f << " const uint32_t new_" << event_name_l << "_capacity = events->" << event_name_l << "_capacity * 2 + 1;\n"; + + f << " Tox_Event_" << event_name << " *new_" << event_name_l << " = (Tox_Event_" << event_name << " *)\n"; + f << " realloc(\n"; + + f << " events->" << event_name_l << ",\n"; + f << " new_" << event_name_l << "_capacity * sizeof(Tox_Event_" << event_name << "));\n\n"; + f << " if (new_" << event_name_l << " == nullptr) {\n return nullptr;\n }\n\n"; + f << " events->" << event_name_l << " = new_" << event_name_l << ";\n"; + f << " events->" << event_name_l << "_capacity = new_" << event_name_l << "_capacity;\n"; + f << " }\n\n"; + f << " Tox_Event_" << event_name << " *const " << event_name_l << " =\n"; + f << " &events->" << event_name_l << "[events->" << event_name_l << "_size];\n"; + f << " tox_event_" << event_name_l << "_construct(" << event_name_l << ");\n"; + f << " ++events->" << event_name_l << "_size;\n"; + f << " return " << event_name_l << ";\n}\n\n"; + + // clear + f << "void tox_events_clear_" << event_name_l << "(Tox_Events *events)\n{\n"; + f << " if (events == nullptr) {\n return;\n }\n\n"; + f << " for (uint32_t i = 0; i < events->" << event_name_l << "_size; ++i) {\n"; + f << " tox_event_" << event_name_l << "_destruct(&events->" << event_name_l << "[i]);\n }\n\n"; + f << " free(events->" << event_name_l << ");\n"; + f << " events->" << event_name_l << " = nullptr;\n"; + f << " events->" << event_name_l << "_size = 0;\n"; + f << " events->" << event_name_l << "_capacity = 0;\n"; + f << "}\n\n"; + + // get size + f << "uint32_t tox_events_get_" << event_name_l << "_size(const Tox_Events *events)\n{\n"; + f << " if (events == nullptr) {\n return 0;\n }\n\n"; + f << " return events->" << event_name_l << "_size;\n}\n\n"; + + // get + f << "const Tox_Event_" << event_name << " *tox_events_get_" << event_name_l << "(const Tox_Events *events, uint32_t index)\n{\n"; + f << " assert(index < events->" << event_name_l << "_size);\n"; + f << " assert(events->" << event_name_l << " != nullptr);\n"; + f << " return &events->" << event_name_l << "[index];\n}\n\n"; + + // aux pack + f << "bool tox_events_pack_" << event_name_l << "(const Tox_Events *events, Bin_Pack *bp)\n{\n"; + f << " const uint32_t size = tox_events_get_" << event_name_l << "_size(events);\n\n"; + f << " for (uint32_t i = 0; i < size; ++i) {\n"; + f << " if (!tox_event_" << event_name_l << "_pack(tox_events_get_" << event_name_l << "(events, i), bp)) {\n"; + f << " return false;\n }\n }\n"; + f << " return true;\n}\n\n"; + + // aux unpack + f << "bool tox_events_unpack_" << event_name_l << "(Tox_Events *events, Bin_Unpack *bu)\n{\n"; + f << " Tox_Event_" << event_name << " *event = tox_events_add_" << event_name_l << "(events);\n\n"; + f << " if (event == nullptr) {\n return false;\n }\n\n"; + f << " return tox_event_" << event_name_l << "_unpack(event, bu);\n}\n\n"; + + f << R"( +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +)"; + f << "void tox_events_handle_" << event_name_l << "(Tox *tox"; + + for (const auto& t : event_types) { + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << ", " << t.type << " " << t.name; + }, + [&](const EventTypeByteRange& t) { + f << ", const uint8_t *" << t.name_data << ", size_t " << t.name_length_cb; + } + }, + t + ); + } + + f << ",\n void *user_data)\n{\n"; + f << " Tox_Events_State *state = tox_events_alloc(user_data);\n"; + f << " assert(state != nullptr);\n\n"; + f << " if (state->events == nullptr) {\n return;\n }\n\n"; + f << " Tox_Event_" << event_name << " *" << event_name_l << " = tox_events_add_" << event_name_l << "(state->events);\n\n"; + f << " if (" << event_name_l << " == nullptr) {\n"; + f << " state->error = TOX_ERR_EVENTS_ITERATE_MALLOC;\n return;\n }\n\n"; + + for (const auto& t : event_types) { + std::visit( + overloaded{ + [&](const EventTypeTrivial& t) { + f << " tox_event_" << event_name_l << "_set_" << t.name << "(" << event_name_l << ", " << t.name << ");\n"; + }, + [&](const EventTypeByteRange& t) { + f << " tox_event_" << event_name_l << "_set_" << t.name_data << "(" << event_name_l << ", " << t.name_data << ", " << t.name_length_cb << ");\n"; + } + }, + t + ); + } + f << "}\n"; +} + +// c++ generate_event_c.cpp -std=c++17 && ./a.out Friend_Lossy_Packet && diff --color ../../toxcore/events/friend_lossy_packet.c out/friend_lossy_packet.c +int main(int argc, char** argv) { + // TODO: json? + std::map> event_defs { + { + "Conference_Connected", + { + EventTypeTrivial{"uint32_t", "conference_number"}, + } + }, + { + "Conference_Invite", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"Tox_Conference_Type", "type"}, + EventTypeByteRange{"cookie", "cookie_length", "length"}, // the later two are idealy the same + } + }, + { + "Conference_Message", + { + EventTypeTrivial{"uint32_t", "conference_number"}, + EventTypeTrivial{"uint32_t", "peer_number"}, + EventTypeTrivial{"Tox_Message_Type", "type"}, + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + } + }, + { + "Conference_Peer_List_Changed", + { + EventTypeTrivial{"uint32_t", "conference_number"}, + } + }, + { + "Conference_Peer_Name", + { + EventTypeTrivial{"uint32_t", "conference_number"}, + EventTypeTrivial{"uint32_t", "peer_number"}, + EventTypeByteRange{"name", "name_length", "length"}, // the later two are idealy the same + } + }, + { + "Conference_Title", + { + EventTypeTrivial{"uint32_t", "conference_number"}, + EventTypeTrivial{"uint32_t", "peer_number"}, + EventTypeByteRange{"title", "title_length", "length"}, // the later two are idealy the same + } + }, + + { + "File_Chunk_Request", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"uint32_t", "file_number"}, + EventTypeTrivial{"uint64_t", "position"}, + EventTypeTrivial{"uint16_t", "length"}, + } + }, + { + "File_Recv", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"uint32_t", "file_number"}, + EventTypeTrivial{"uint32_t", "kind"}, + EventTypeTrivial{"uint64_t", "file_size"}, + EventTypeByteRange{"filename", "filename_length", "length"}, // the later two are idealy the same + } + }, + { + "File_Recv_Chunk", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"uint32_t", "file_number"}, + EventTypeTrivial{"uint64_t", "position"}, + EventTypeByteRange{"data", "data_length", "length"}, // the later two are idealy the same + } + }, + { + "File_Recv_Control", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"uint32_t", "file_number"}, + EventTypeTrivial{"Tox_File_Control", "control"}, + } + }, + + { + "Friend_Connection_Status", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"Tox_Connection", "connection_status"}, + } + }, + { + "Friend_Lossless_Packet", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeByteRange{"data", "data_length", "length"}, // the later two are idealy the same + } + }, + { + "Friend_Lossy_Packet", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeByteRange{"data", "data_length", "length"}, // the later two are idealy the same + } + }, + { + "Friend_Message", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"Tox_Message_Type", "type"}, + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + } + }, + { + "Friend_Name", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeByteRange{"name", "name_length", "length"}, // the later two are idealy the same + } + }, + { + "Friend_Read_Receipt", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"uint32_t", "message_id"}, + } + }, +#if 0 + { + "Friend_Request", + { + //EventTypeTrivial{"uint32_t", "friend_number"}, // public_key ByteArray + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + } + }, +#endif + { + "Friend_Status", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"Tox_User_Status", "status"}, + } + }, + { + "Friend_Status_Message", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + } + }, + { + "Friend_Typing", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeTrivial{"bool", "typing"}, + } + }, + + { + "Self_Connection_Status", + { + EventTypeTrivial{"Tox_Connection", "connection_status"}, + } + }, + + { + "Group_Peer_Name", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeByteRange{"name", "name_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Peer_Status", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeTrivial{"Tox_User_Status", "status"}, + } + }, + { + "Group_Topic", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeByteRange{"topic", "topic_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Privacy_State", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"Tox_Group_Privacy_State", "privacy_state"}, + } + }, + { + "Group_Voice_State", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"Tox_Group_Voice_State", "voice_state"}, + } + }, + { + "Group_Topic_Lock", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"Tox_Group_Topic_Lock", "topic_lock"}, + } + }, + { + "Group_Peer_Limit", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_limit"}, + } + }, + { + "Group_Password", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeByteRange{"password", "password_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Message", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeTrivial{"Tox_Message_Type", "type"}, + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + EventTypeTrivial{"uint32_t", "message_id"}, + } + }, + { + "Group_Private_Message", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeTrivial{"Tox_Message_Type", "type"}, + EventTypeByteRange{"message", "message_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Custom_Packet", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeByteRange{"data", "data_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Custom_Private_Packet", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeByteRange{"data", "data_length", "length"}, // the later two are idealy the same + } + }, + { + "Group_Invite", + { + EventTypeTrivial{"uint32_t", "friend_number"}, + EventTypeByteRange{"invite_data", "invite_data_length", "length"}, // the later two are idealy the same + EventTypeByteRange{"group_name", "group_name_length", "group_name_length"}, // they are :) + } + }, + { + "Group_Peer_Join", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + } + }, + { + "Group_Peer_Exit", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "peer_id"}, + EventTypeTrivial{"Tox_Group_Exit_Type", "exit_type"}, + EventTypeByteRange{"name", "name_length", "name_length"}, // they are :) + EventTypeByteRange{"part_message", "part_message_length", "part_message_length"}, // they are :) + } + }, + { + "Group_Self_Join", + { + EventTypeTrivial{"uint32_t", "group_number"}, + } + }, + { + "Group_Join_Fail", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"Tox_Group_Join_Fail", "fail_type"}, + } + }, + { + "Group_Moderation", + { + EventTypeTrivial{"uint32_t", "group_number"}, + EventTypeTrivial{"uint32_t", "source_peer_id"}, + EventTypeTrivial{"uint32_t", "target_peer_id"}, + EventTypeTrivial{"Tox_Group_Mod_Event", "mod_type"}, + } + }, + }; + + if (argc < 2) { + for (const auto& [event, event_types] : event_defs) { + generate_event_impl(event, event_types); + } + } else { + if (event_defs.count(argv[1])) { + generate_event_impl(argv[1], event_defs[argv[1]]); + } else { + std::cerr << "error: unknown event " << argv[1] << "\n"; + return 1; + } + } + + return 0; +} + diff --git a/toxcore/Makefile.inc b/toxcore/Makefile.inc index e5f0ddf91d..270b308419 100644 --- a/toxcore/Makefile.inc +++ b/toxcore/Makefile.inc @@ -37,6 +37,24 @@ libtoxcore_la_SOURCES = ../third_party/cmp/cmp.c \ ../toxcore/events/events_alloc.c \ ../toxcore/events/events_alloc.h \ ../toxcore/events/self_connection_status.c \ + ../toxcore/events/group_custom_packet.c \ + ../toxcore/events/group_custom_private_packet.c \ + ../toxcore/events/group_invite.c \ + ../toxcore/events/group_join_fail.c \ + ../toxcore/events/group_message.c \ + ../toxcore/events/group_moderation.c \ + ../toxcore/events/group_password.c \ + ../toxcore/events/group_peer_exit.c \ + ../toxcore/events/group_peer_join.c \ + ../toxcore/events/group_peer_limit.c \ + ../toxcore/events/group_peer_name.c \ + ../toxcore/events/group_peer_status.c \ + ../toxcore/events/group_privacy_state.c \ + ../toxcore/events/group_private_message.c \ + ../toxcore/events/group_self_join.c \ + ../toxcore/events/group_topic.c \ + ../toxcore/events/group_topic_lock.c \ + ../toxcore/events/group_voice_state.c \ ../toxcore/DHT.h \ ../toxcore/DHT.c \ ../toxcore/mono_time.h \ diff --git a/toxcore/events/events_alloc.c b/toxcore/events/events_alloc.c index f661c5c039..ba9c57737a 100644 --- a/toxcore/events/events_alloc.c +++ b/toxcore/events/events_alloc.c @@ -60,5 +60,23 @@ void tox_events_free(Tox_Events *events) tox_events_clear_friend_status_message(events); tox_events_clear_friend_typing(events); tox_events_clear_self_connection_status(events); + tox_events_clear_group_peer_name(events); + tox_events_clear_group_peer_status(events); + tox_events_clear_group_topic(events); + tox_events_clear_group_privacy_state(events); + tox_events_clear_group_voice_state(events); + tox_events_clear_group_topic_lock(events); + tox_events_clear_group_peer_limit(events); + tox_events_clear_group_password(events); + tox_events_clear_group_message(events); + tox_events_clear_group_private_message(events); + tox_events_clear_group_custom_packet(events); + tox_events_clear_group_custom_private_packet(events); + tox_events_clear_group_invite(events); + tox_events_clear_group_peer_join(events); + tox_events_clear_group_peer_exit(events); + tox_events_clear_group_self_join(events); + tox_events_clear_group_join_fail(events); + tox_events_clear_group_moderation(events); free(events); } diff --git a/toxcore/events/events_alloc.h b/toxcore/events/events_alloc.h index 6c5a7abd4f..769c119486 100644 --- a/toxcore/events/events_alloc.h +++ b/toxcore/events/events_alloc.h @@ -98,6 +98,78 @@ struct Tox_Events { Tox_Event_Self_Connection_Status *self_connection_status; uint32_t self_connection_status_size; uint32_t self_connection_status_capacity; + + Tox_Event_Group_Peer_Name *group_peer_name; + uint32_t group_peer_name_size; + uint32_t group_peer_name_capacity; + + Tox_Event_Group_Peer_Status *group_peer_status; + uint32_t group_peer_status_size; + uint32_t group_peer_status_capacity; + + Tox_Event_Group_Topic *group_topic; + uint32_t group_topic_size; + uint32_t group_topic_capacity; + + Tox_Event_Group_Privacy_State *group_privacy_state; + uint32_t group_privacy_state_size; + uint32_t group_privacy_state_capacity; + + Tox_Event_Group_Voice_State *group_voice_state; + uint32_t group_voice_state_size; + uint32_t group_voice_state_capacity; + + Tox_Event_Group_Topic_Lock *group_topic_lock; + uint32_t group_topic_lock_size; + uint32_t group_topic_lock_capacity; + + Tox_Event_Group_Peer_Limit *group_peer_limit; + uint32_t group_peer_limit_size; + uint32_t group_peer_limit_capacity; + + Tox_Event_Group_Password *group_password; + uint32_t group_password_size; + uint32_t group_password_capacity; + + Tox_Event_Group_Message *group_message; + uint32_t group_message_size; + uint32_t group_message_capacity; + + Tox_Event_Group_Private_Message *group_private_message; + uint32_t group_private_message_size; + uint32_t group_private_message_capacity; + + Tox_Event_Group_Custom_Packet *group_custom_packet; + uint32_t group_custom_packet_size; + uint32_t group_custom_packet_capacity; + + Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet; + uint32_t group_custom_private_packet_size; + uint32_t group_custom_private_packet_capacity; + + Tox_Event_Group_Invite *group_invite; + uint32_t group_invite_size; + uint32_t group_invite_capacity; + + Tox_Event_Group_Peer_Join *group_peer_join; + uint32_t group_peer_join_size; + uint32_t group_peer_join_capacity; + + Tox_Event_Group_Peer_Exit *group_peer_exit; + uint32_t group_peer_exit_size; + uint32_t group_peer_exit_capacity; + + Tox_Event_Group_Self_Join *group_self_join; + uint32_t group_self_join_size; + uint32_t group_self_join_capacity; + + Tox_Event_Group_Join_Fail *group_join_fail; + uint32_t group_join_fail_size; + uint32_t group_join_fail_capacity; + + Tox_Event_Group_Moderation *group_moderation; + uint32_t group_moderation_size; + uint32_t group_moderation_capacity; }; typedef struct Tox_Events_State { @@ -126,6 +198,24 @@ tox_friend_status_cb tox_events_handle_friend_status; tox_friend_status_message_cb tox_events_handle_friend_status_message; tox_friend_typing_cb tox_events_handle_friend_typing; tox_self_connection_status_cb tox_events_handle_self_connection_status; +tox_group_peer_name_cb tox_events_handle_group_peer_name; +tox_group_peer_status_cb tox_events_handle_group_peer_status; +tox_group_topic_cb tox_events_handle_group_topic; +tox_group_privacy_state_cb tox_events_handle_group_privacy_state; +tox_group_voice_state_cb tox_events_handle_group_voice_state; +tox_group_topic_lock_cb tox_events_handle_group_topic_lock; +tox_group_peer_limit_cb tox_events_handle_group_peer_limit; +tox_group_password_cb tox_events_handle_group_password; +tox_group_message_cb tox_events_handle_group_message; +tox_group_private_message_cb tox_events_handle_group_private_message; +tox_group_custom_packet_cb tox_events_handle_group_custom_packet; +tox_group_custom_private_packet_cb tox_events_handle_group_custom_private_packet; +tox_group_invite_cb tox_events_handle_group_invite; +tox_group_peer_join_cb tox_events_handle_group_peer_join; +tox_group_peer_exit_cb tox_events_handle_group_peer_exit; +tox_group_self_join_cb tox_events_handle_group_self_join; +tox_group_join_fail_cb tox_events_handle_group_join_fail; +tox_group_moderation_cb tox_events_handle_group_moderation; // non_null() typedef void tox_events_clear_cb(Tox_Events *events); @@ -151,6 +241,24 @@ tox_events_clear_cb tox_events_clear_friend_status_message; tox_events_clear_cb tox_events_clear_friend_status; tox_events_clear_cb tox_events_clear_friend_typing; tox_events_clear_cb tox_events_clear_self_connection_status; +tox_events_clear_cb tox_events_clear_group_peer_name; +tox_events_clear_cb tox_events_clear_group_peer_status; +tox_events_clear_cb tox_events_clear_group_topic; +tox_events_clear_cb tox_events_clear_group_privacy_state; +tox_events_clear_cb tox_events_clear_group_voice_state; +tox_events_clear_cb tox_events_clear_group_topic_lock; +tox_events_clear_cb tox_events_clear_group_peer_limit; +tox_events_clear_cb tox_events_clear_group_password; +tox_events_clear_cb tox_events_clear_group_message; +tox_events_clear_cb tox_events_clear_group_private_message; +tox_events_clear_cb tox_events_clear_group_custom_packet; +tox_events_clear_cb tox_events_clear_group_custom_private_packet; +tox_events_clear_cb tox_events_clear_group_invite; +tox_events_clear_cb tox_events_clear_group_peer_join; +tox_events_clear_cb tox_events_clear_group_peer_exit; +tox_events_clear_cb tox_events_clear_group_self_join; +tox_events_clear_cb tox_events_clear_group_join_fail; +tox_events_clear_cb tox_events_clear_group_moderation; // non_null() typedef bool tox_events_pack_cb(const Tox_Events *events, Bin_Pack *bp); @@ -176,6 +284,24 @@ tox_events_pack_cb tox_events_pack_friend_status_message; tox_events_pack_cb tox_events_pack_friend_status; tox_events_pack_cb tox_events_pack_friend_typing; tox_events_pack_cb tox_events_pack_self_connection_status; +tox_events_pack_cb tox_events_pack_group_peer_name; +tox_events_pack_cb tox_events_pack_group_peer_status; +tox_events_pack_cb tox_events_pack_group_topic; +tox_events_pack_cb tox_events_pack_group_privacy_state; +tox_events_pack_cb tox_events_pack_group_voice_state; +tox_events_pack_cb tox_events_pack_group_topic_lock; +tox_events_pack_cb tox_events_pack_group_peer_limit; +tox_events_pack_cb tox_events_pack_group_password; +tox_events_pack_cb tox_events_pack_group_message; +tox_events_pack_cb tox_events_pack_group_private_message; +tox_events_pack_cb tox_events_pack_group_custom_packet; +tox_events_pack_cb tox_events_pack_group_custom_private_packet; +tox_events_pack_cb tox_events_pack_group_invite; +tox_events_pack_cb tox_events_pack_group_peer_join; +tox_events_pack_cb tox_events_pack_group_peer_exit; +tox_events_pack_cb tox_events_pack_group_self_join; +tox_events_pack_cb tox_events_pack_group_join_fail; +tox_events_pack_cb tox_events_pack_group_moderation; tox_events_pack_cb tox_events_pack; @@ -203,6 +329,24 @@ tox_events_unpack_cb tox_events_unpack_friend_status_message; tox_events_unpack_cb tox_events_unpack_friend_status; tox_events_unpack_cb tox_events_unpack_friend_typing; tox_events_unpack_cb tox_events_unpack_self_connection_status; +tox_events_unpack_cb tox_events_unpack_group_peer_name; +tox_events_unpack_cb tox_events_unpack_group_peer_status; +tox_events_unpack_cb tox_events_unpack_group_topic; +tox_events_unpack_cb tox_events_unpack_group_privacy_state; +tox_events_unpack_cb tox_events_unpack_group_voice_state; +tox_events_unpack_cb tox_events_unpack_group_topic_lock; +tox_events_unpack_cb tox_events_unpack_group_peer_limit; +tox_events_unpack_cb tox_events_unpack_group_password; +tox_events_unpack_cb tox_events_unpack_group_message; +tox_events_unpack_cb tox_events_unpack_group_private_message; +tox_events_unpack_cb tox_events_unpack_group_custom_packet; +tox_events_unpack_cb tox_events_unpack_group_custom_private_packet; +tox_events_unpack_cb tox_events_unpack_group_invite; +tox_events_unpack_cb tox_events_unpack_group_peer_join; +tox_events_unpack_cb tox_events_unpack_group_peer_exit; +tox_events_unpack_cb tox_events_unpack_group_self_join; +tox_events_unpack_cb tox_events_unpack_group_join_fail; +tox_events_unpack_cb tox_events_unpack_group_moderation; tox_events_unpack_cb tox_events_unpack; diff --git a/toxcore/events/friend_status.c b/toxcore/events/friend_status.c index c6eabdaa47..1e1e934137 100644 --- a/toxcore/events/friend_status.c +++ b/toxcore/events/friend_status.c @@ -7,9 +7,9 @@ #include #include #include -#include "../bin_unpack.h" #include "../bin_pack.h" +#include "../bin_unpack.h" #include "../ccompat.h" #include "../tox.h" #include "../tox_events.h" diff --git a/toxcore/events/group_custom_packet.c b/toxcore/events/group_custom_packet.c new file mode 100644 index 0000000000..395c4eeb96 --- /dev/null +++ b/toxcore/events/group_custom_packet.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Custom_Packet { + uint32_t group_number; + uint32_t peer_id; + uint8_t *data; + uint32_t data_length; +}; + +non_null() +static void tox_event_group_custom_packet_construct(Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + *group_custom_packet = (Tox_Event_Group_Custom_Packet) { + 0 + }; +} +non_null() +static void tox_event_group_custom_packet_destruct(Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + free(group_custom_packet->data); +} + +non_null() +static void tox_event_group_custom_packet_set_group_number(Tox_Event_Group_Custom_Packet *group_custom_packet, + uint32_t group_number) +{ + assert(group_custom_packet != nullptr); + group_custom_packet->group_number = group_number; +} +uint32_t tox_event_group_custom_packet_get_group_number(const Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + assert(group_custom_packet != nullptr); + return group_custom_packet->group_number; +} + +non_null() +static void tox_event_group_custom_packet_set_peer_id(Tox_Event_Group_Custom_Packet *group_custom_packet, + uint32_t peer_id) +{ + assert(group_custom_packet != nullptr); + group_custom_packet->peer_id = peer_id; +} +uint32_t tox_event_group_custom_packet_get_peer_id(const Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + assert(group_custom_packet != nullptr); + return group_custom_packet->peer_id; +} + +non_null() +static bool tox_event_group_custom_packet_set_data(Tox_Event_Group_Custom_Packet *group_custom_packet, + const uint8_t *data, uint32_t data_length) +{ + assert(group_custom_packet != nullptr); + + if (group_custom_packet->data != nullptr) { + free(group_custom_packet->data); + group_custom_packet->data = nullptr; + group_custom_packet->data_length = 0; + } + + group_custom_packet->data = (uint8_t *)malloc(data_length); + + if (group_custom_packet->data == nullptr) { + return false; + } + + memcpy(group_custom_packet->data, data, data_length); + group_custom_packet->data_length = data_length; + return true; +} +size_t tox_event_group_custom_packet_get_data_length(const Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + assert(group_custom_packet != nullptr); + return group_custom_packet->data_length; +} +const uint8_t *tox_event_group_custom_packet_get_data(const Tox_Event_Group_Custom_Packet *group_custom_packet) +{ + assert(group_custom_packet != nullptr); + return group_custom_packet->data; +} + +non_null() +static bool tox_event_group_custom_packet_pack( + const Tox_Event_Group_Custom_Packet *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_CUSTOM_PACKET) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_bin(bp, event->data, event->data_length); +} + +non_null() +static bool tox_event_group_custom_packet_unpack( + Tox_Event_Group_Custom_Packet *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && bin_unpack_bin(bu, &event->data, &event->data_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Custom_Packet *tox_events_add_group_custom_packet(Tox_Events *events) +{ + if (events->group_custom_packet_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_custom_packet_size == events->group_custom_packet_capacity) { + const uint32_t new_group_custom_packet_capacity = events->group_custom_packet_capacity * 2 + 1; + Tox_Event_Group_Custom_Packet *new_group_custom_packet = (Tox_Event_Group_Custom_Packet *) + realloc( + events->group_custom_packet, + new_group_custom_packet_capacity * sizeof(Tox_Event_Group_Custom_Packet)); + + if (new_group_custom_packet == nullptr) { + return nullptr; + } + + events->group_custom_packet = new_group_custom_packet; + events->group_custom_packet_capacity = new_group_custom_packet_capacity; + } + + Tox_Event_Group_Custom_Packet *const group_custom_packet = + &events->group_custom_packet[events->group_custom_packet_size]; + tox_event_group_custom_packet_construct(group_custom_packet); + ++events->group_custom_packet_size; + return group_custom_packet; +} + +void tox_events_clear_group_custom_packet(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_custom_packet_size; ++i) { + tox_event_group_custom_packet_destruct(&events->group_custom_packet[i]); + } + + free(events->group_custom_packet); + events->group_custom_packet = nullptr; + events->group_custom_packet_size = 0; + events->group_custom_packet_capacity = 0; +} + +uint32_t tox_events_get_group_custom_packet_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_custom_packet_size; +} + +const Tox_Event_Group_Custom_Packet *tox_events_get_group_custom_packet(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_custom_packet_size); + assert(events->group_custom_packet != nullptr); + return &events->group_custom_packet[index]; +} + +bool tox_events_pack_group_custom_packet(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_custom_packet_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_custom_packet_pack(tox_events_get_group_custom_packet(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_custom_packet(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Custom_Packet *event = tox_events_add_group_custom_packet(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_custom_packet_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_custom_packet(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Custom_Packet *group_custom_packet = tox_events_add_group_custom_packet(state->events); + + if (group_custom_packet == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_custom_packet_set_group_number(group_custom_packet, group_number); + tox_event_group_custom_packet_set_peer_id(group_custom_packet, peer_id); + tox_event_group_custom_packet_set_data(group_custom_packet, data, length); +} diff --git a/toxcore/events/group_custom_private_packet.c b/toxcore/events/group_custom_private_packet.c new file mode 100644 index 0000000000..bbae86589e --- /dev/null +++ b/toxcore/events/group_custom_private_packet.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Custom_Private_Packet { + uint32_t group_number; + uint32_t peer_id; + uint8_t *data; + uint32_t data_length; +}; + +non_null() +static void tox_event_group_custom_private_packet_construct(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + *group_custom_private_packet = (Tox_Event_Group_Custom_Private_Packet) { + 0 + }; +} +non_null() +static void tox_event_group_custom_private_packet_destruct(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + free(group_custom_private_packet->data); +} + +non_null() +static void tox_event_group_custom_private_packet_set_group_number(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, + uint32_t group_number) +{ + assert(group_custom_private_packet != nullptr); + group_custom_private_packet->group_number = group_number; +} +uint32_t tox_event_group_custom_private_packet_get_group_number(const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + assert(group_custom_private_packet != nullptr); + return group_custom_private_packet->group_number; +} + +non_null() +static void tox_event_group_custom_private_packet_set_peer_id(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, + uint32_t peer_id) +{ + assert(group_custom_private_packet != nullptr); + group_custom_private_packet->peer_id = peer_id; +} +uint32_t tox_event_group_custom_private_packet_get_peer_id(const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + assert(group_custom_private_packet != nullptr); + return group_custom_private_packet->peer_id; +} + +non_null() +static bool tox_event_group_custom_private_packet_set_data(Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet, + const uint8_t *data, uint32_t data_length) +{ + assert(group_custom_private_packet != nullptr); + + if (group_custom_private_packet->data != nullptr) { + free(group_custom_private_packet->data); + group_custom_private_packet->data = nullptr; + group_custom_private_packet->data_length = 0; + } + + group_custom_private_packet->data = (uint8_t *)malloc(data_length); + + if (group_custom_private_packet->data == nullptr) { + return false; + } + + memcpy(group_custom_private_packet->data, data, data_length); + group_custom_private_packet->data_length = data_length; + return true; +} +size_t tox_event_group_custom_private_packet_get_data_length(const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + assert(group_custom_private_packet != nullptr); + return group_custom_private_packet->data_length; +} +const uint8_t *tox_event_group_custom_private_packet_get_data(const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet) +{ + assert(group_custom_private_packet != nullptr); + return group_custom_private_packet->data; +} + +non_null() +static bool tox_event_group_custom_private_packet_pack( + const Tox_Event_Group_Custom_Private_Packet *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_bin(bp, event->data, event->data_length); +} + +non_null() +static bool tox_event_group_custom_private_packet_unpack( + Tox_Event_Group_Custom_Private_Packet *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && bin_unpack_bin(bu, &event->data, &event->data_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Custom_Private_Packet *tox_events_add_group_custom_private_packet(Tox_Events *events) +{ + if (events->group_custom_private_packet_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_custom_private_packet_size == events->group_custom_private_packet_capacity) { + const uint32_t new_group_custom_private_packet_capacity = events->group_custom_private_packet_capacity * 2 + 1; + Tox_Event_Group_Custom_Private_Packet *new_group_custom_private_packet = (Tox_Event_Group_Custom_Private_Packet *) + realloc( + events->group_custom_private_packet, + new_group_custom_private_packet_capacity * sizeof(Tox_Event_Group_Custom_Private_Packet)); + + if (new_group_custom_private_packet == nullptr) { + return nullptr; + } + + events->group_custom_private_packet = new_group_custom_private_packet; + events->group_custom_private_packet_capacity = new_group_custom_private_packet_capacity; + } + + Tox_Event_Group_Custom_Private_Packet *const group_custom_private_packet = + &events->group_custom_private_packet[events->group_custom_private_packet_size]; + tox_event_group_custom_private_packet_construct(group_custom_private_packet); + ++events->group_custom_private_packet_size; + return group_custom_private_packet; +} + +void tox_events_clear_group_custom_private_packet(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_custom_private_packet_size; ++i) { + tox_event_group_custom_private_packet_destruct(&events->group_custom_private_packet[i]); + } + + free(events->group_custom_private_packet); + events->group_custom_private_packet = nullptr; + events->group_custom_private_packet_size = 0; + events->group_custom_private_packet_capacity = 0; +} + +uint32_t tox_events_get_group_custom_private_packet_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_custom_private_packet_size; +} + +const Tox_Event_Group_Custom_Private_Packet *tox_events_get_group_custom_private_packet(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_custom_private_packet_size); + assert(events->group_custom_private_packet != nullptr); + return &events->group_custom_private_packet[index]; +} + +bool tox_events_pack_group_custom_private_packet(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_custom_private_packet_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_custom_private_packet_pack(tox_events_get_group_custom_private_packet(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_custom_private_packet(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Custom_Private_Packet *event = tox_events_add_group_custom_private_packet(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_custom_private_packet_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_custom_private_packet(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *data, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet = tox_events_add_group_custom_private_packet(state->events); + + if (group_custom_private_packet == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_custom_private_packet_set_group_number(group_custom_private_packet, group_number); + tox_event_group_custom_private_packet_set_peer_id(group_custom_private_packet, peer_id); + tox_event_group_custom_private_packet_set_data(group_custom_private_packet, data, length); +} diff --git a/toxcore/events/group_invite.c b/toxcore/events/group_invite.c new file mode 100644 index 0000000000..dddc1f48fb --- /dev/null +++ b/toxcore/events/group_invite.c @@ -0,0 +1,274 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Invite { + uint32_t friend_number; + uint8_t *invite_data; + uint32_t invite_data_length; + uint8_t *group_name; + uint32_t group_name_length; +}; + +non_null() +static void tox_event_group_invite_construct(Tox_Event_Group_Invite *group_invite) +{ + *group_invite = (Tox_Event_Group_Invite) { + 0 + }; +} +non_null() +static void tox_event_group_invite_destruct(Tox_Event_Group_Invite *group_invite) +{ + free(group_invite->invite_data); + free(group_invite->group_name); +} + +non_null() +static void tox_event_group_invite_set_friend_number(Tox_Event_Group_Invite *group_invite, + uint32_t friend_number) +{ + assert(group_invite != nullptr); + group_invite->friend_number = friend_number; +} +uint32_t tox_event_group_invite_get_friend_number(const Tox_Event_Group_Invite *group_invite) +{ + assert(group_invite != nullptr); + return group_invite->friend_number; +} + +non_null() +static bool tox_event_group_invite_set_invite_data(Tox_Event_Group_Invite *group_invite, + const uint8_t *invite_data, uint32_t invite_data_length) +{ + assert(group_invite != nullptr); + + if (group_invite->invite_data != nullptr) { + free(group_invite->invite_data); + group_invite->invite_data = nullptr; + group_invite->invite_data_length = 0; + } + + group_invite->invite_data = (uint8_t *)malloc(invite_data_length); + + if (group_invite->invite_data == nullptr) { + return false; + } + + memcpy(group_invite->invite_data, invite_data, invite_data_length); + group_invite->invite_data_length = invite_data_length; + return true; +} +size_t tox_event_group_invite_get_invite_data_length(const Tox_Event_Group_Invite *group_invite) +{ + assert(group_invite != nullptr); + return group_invite->invite_data_length; +} +const uint8_t *tox_event_group_invite_get_invite_data(const Tox_Event_Group_Invite *group_invite) +{ + assert(group_invite != nullptr); + return group_invite->invite_data; +} + +non_null() +static bool tox_event_group_invite_set_group_name(Tox_Event_Group_Invite *group_invite, + const uint8_t *group_name, uint32_t group_name_length) +{ + assert(group_invite != nullptr); + + if (group_invite->group_name != nullptr) { + free(group_invite->group_name); + group_invite->group_name = nullptr; + group_invite->group_name_length = 0; + } + + group_invite->group_name = (uint8_t *)malloc(group_name_length); + + if (group_invite->group_name == nullptr) { + return false; + } + + memcpy(group_invite->group_name, group_name, group_name_length); + group_invite->group_name_length = group_name_length; + return true; +} +size_t tox_event_group_invite_get_group_name_length(const Tox_Event_Group_Invite *group_invite) +{ + assert(group_invite != nullptr); + return group_invite->group_name_length; +} +const uint8_t *tox_event_group_invite_get_group_name(const Tox_Event_Group_Invite *group_invite) +{ + assert(group_invite != nullptr); + return group_invite->group_name; +} + +non_null() +static bool tox_event_group_invite_pack( + const Tox_Event_Group_Invite *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_INVITE) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->friend_number) + && bin_pack_bin(bp, event->invite_data, event->invite_data_length) + && bin_pack_bin(bp, event->group_name, event->group_name_length); +} + +non_null() +static bool tox_event_group_invite_unpack( + Tox_Event_Group_Invite *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->friend_number) + && bin_unpack_bin(bu, &event->invite_data, &event->invite_data_length) + && bin_unpack_bin(bu, &event->group_name, &event->group_name_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Invite *tox_events_add_group_invite(Tox_Events *events) +{ + if (events->group_invite_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_invite_size == events->group_invite_capacity) { + const uint32_t new_group_invite_capacity = events->group_invite_capacity * 2 + 1; + Tox_Event_Group_Invite *new_group_invite = (Tox_Event_Group_Invite *) + realloc( + events->group_invite, + new_group_invite_capacity * sizeof(Tox_Event_Group_Invite)); + + if (new_group_invite == nullptr) { + return nullptr; + } + + events->group_invite = new_group_invite; + events->group_invite_capacity = new_group_invite_capacity; + } + + Tox_Event_Group_Invite *const group_invite = + &events->group_invite[events->group_invite_size]; + tox_event_group_invite_construct(group_invite); + ++events->group_invite_size; + return group_invite; +} + +void tox_events_clear_group_invite(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_invite_size; ++i) { + tox_event_group_invite_destruct(&events->group_invite[i]); + } + + free(events->group_invite); + events->group_invite = nullptr; + events->group_invite_size = 0; + events->group_invite_capacity = 0; +} + +uint32_t tox_events_get_group_invite_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_invite_size; +} + +const Tox_Event_Group_Invite *tox_events_get_group_invite(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_invite_size); + assert(events->group_invite != nullptr); + return &events->group_invite[index]; +} + +bool tox_events_pack_group_invite(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_invite_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_invite_pack(tox_events_get_group_invite(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_invite(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Invite *event = tox_events_add_group_invite(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_invite_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_invite(Tox *tox, uint32_t friend_number, const uint8_t *invite_data, size_t length, const uint8_t *group_name, size_t group_name_length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Invite *group_invite = tox_events_add_group_invite(state->events); + + if (group_invite == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_invite_set_friend_number(group_invite, friend_number); + tox_event_group_invite_set_invite_data(group_invite, invite_data, length); + tox_event_group_invite_set_group_name(group_invite, group_name, group_name_length); +} diff --git a/toxcore/events/group_join_fail.c b/toxcore/events/group_join_fail.c new file mode 100644 index 0000000000..c6c28531e1 --- /dev/null +++ b/toxcore/events/group_join_fail.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Join_Fail { + uint32_t group_number; + Tox_Group_Join_Fail fail_type; +}; + +non_null() +static void tox_event_group_join_fail_construct(Tox_Event_Group_Join_Fail *group_join_fail) +{ + *group_join_fail = (Tox_Event_Group_Join_Fail) { + 0 + }; +} +non_null() +static void tox_event_group_join_fail_destruct(Tox_Event_Group_Join_Fail *group_join_fail) +{ + return; +} + +non_null() +static void tox_event_group_join_fail_set_group_number(Tox_Event_Group_Join_Fail *group_join_fail, + uint32_t group_number) +{ + assert(group_join_fail != nullptr); + group_join_fail->group_number = group_number; +} +uint32_t tox_event_group_join_fail_get_group_number(const Tox_Event_Group_Join_Fail *group_join_fail) +{ + assert(group_join_fail != nullptr); + return group_join_fail->group_number; +} + +non_null() +static void tox_event_group_join_fail_set_fail_type(Tox_Event_Group_Join_Fail *group_join_fail, + Tox_Group_Join_Fail fail_type) +{ + assert(group_join_fail != nullptr); + group_join_fail->fail_type = fail_type; +} +Tox_Group_Join_Fail tox_event_group_join_fail_get_fail_type(const Tox_Event_Group_Join_Fail *group_join_fail) +{ + assert(group_join_fail != nullptr); + return group_join_fail->fail_type; +} + +non_null() +static bool tox_event_group_join_fail_pack( + const Tox_Event_Group_Join_Fail *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_JOIN_FAIL) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->fail_type); +} + +non_null() +static bool tox_event_group_join_fail_unpack( + Tox_Event_Group_Join_Fail *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && tox_unpack_group_join_fail(bu, &event->fail_type); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Join_Fail *tox_events_add_group_join_fail(Tox_Events *events) +{ + if (events->group_join_fail_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_join_fail_size == events->group_join_fail_capacity) { + const uint32_t new_group_join_fail_capacity = events->group_join_fail_capacity * 2 + 1; + Tox_Event_Group_Join_Fail *new_group_join_fail = (Tox_Event_Group_Join_Fail *) + realloc( + events->group_join_fail, + new_group_join_fail_capacity * sizeof(Tox_Event_Group_Join_Fail)); + + if (new_group_join_fail == nullptr) { + return nullptr; + } + + events->group_join_fail = new_group_join_fail; + events->group_join_fail_capacity = new_group_join_fail_capacity; + } + + Tox_Event_Group_Join_Fail *const group_join_fail = + &events->group_join_fail[events->group_join_fail_size]; + tox_event_group_join_fail_construct(group_join_fail); + ++events->group_join_fail_size; + return group_join_fail; +} + +void tox_events_clear_group_join_fail(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_join_fail_size; ++i) { + tox_event_group_join_fail_destruct(&events->group_join_fail[i]); + } + + free(events->group_join_fail); + events->group_join_fail = nullptr; + events->group_join_fail_size = 0; + events->group_join_fail_capacity = 0; +} + +uint32_t tox_events_get_group_join_fail_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_join_fail_size; +} + +const Tox_Event_Group_Join_Fail *tox_events_get_group_join_fail(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_join_fail_size); + assert(events->group_join_fail != nullptr); + return &events->group_join_fail[index]; +} + +bool tox_events_pack_group_join_fail(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_join_fail_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_join_fail_pack(tox_events_get_group_join_fail(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_join_fail(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Join_Fail *event = tox_events_add_group_join_fail(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_join_fail_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_join_fail(Tox *tox, uint32_t group_number, Tox_Group_Join_Fail fail_type, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Join_Fail *group_join_fail = tox_events_add_group_join_fail(state->events); + + if (group_join_fail == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_join_fail_set_group_number(group_join_fail, group_number); + tox_event_group_join_fail_set_fail_type(group_join_fail, fail_type); +} diff --git a/toxcore/events/group_message.c b/toxcore/events/group_message.c new file mode 100644 index 0000000000..ab4d23d419 --- /dev/null +++ b/toxcore/events/group_message.c @@ -0,0 +1,286 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Message { + uint32_t group_number; + uint32_t peer_id; + Tox_Message_Type type; + uint8_t *message; + uint32_t message_length; + uint32_t message_id; +}; + +non_null() +static void tox_event_group_message_construct(Tox_Event_Group_Message *group_message) +{ + *group_message = (Tox_Event_Group_Message) { + 0 + }; +} +non_null() +static void tox_event_group_message_destruct(Tox_Event_Group_Message *group_message) +{ + free(group_message->message); +} + +non_null() +static void tox_event_group_message_set_group_number(Tox_Event_Group_Message *group_message, + uint32_t group_number) +{ + assert(group_message != nullptr); + group_message->group_number = group_number; +} +uint32_t tox_event_group_message_get_group_number(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->group_number; +} + +non_null() +static void tox_event_group_message_set_peer_id(Tox_Event_Group_Message *group_message, + uint32_t peer_id) +{ + assert(group_message != nullptr); + group_message->peer_id = peer_id; +} +uint32_t tox_event_group_message_get_peer_id(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->peer_id; +} + +non_null() +static void tox_event_group_message_set_type(Tox_Event_Group_Message *group_message, + Tox_Message_Type type) +{ + assert(group_message != nullptr); + group_message->type = type; +} +Tox_Message_Type tox_event_group_message_get_type(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->type; +} + +non_null() +static bool tox_event_group_message_set_message(Tox_Event_Group_Message *group_message, + const uint8_t *message, uint32_t message_length) +{ + assert(group_message != nullptr); + + if (group_message->message != nullptr) { + free(group_message->message); + group_message->message = nullptr; + group_message->message_length = 0; + } + + group_message->message = (uint8_t *)malloc(message_length); + + if (group_message->message == nullptr) { + return false; + } + + memcpy(group_message->message, message, message_length); + group_message->message_length = message_length; + return true; +} +size_t tox_event_group_message_get_message_length(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->message_length; +} +const uint8_t *tox_event_group_message_get_message(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->message; +} + +non_null() +static void tox_event_group_message_set_message_id(Tox_Event_Group_Message *group_message, + uint32_t message_id) +{ + assert(group_message != nullptr); + group_message->message_id = message_id; +} +uint32_t tox_event_group_message_get_message_id(const Tox_Event_Group_Message *group_message) +{ + assert(group_message != nullptr); + return group_message->message_id; +} + +non_null() +static bool tox_event_group_message_pack( + const Tox_Event_Group_Message *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_MESSAGE) + && bin_pack_array(bp, 5) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_u32(bp, event->type) + && bin_pack_bin(bp, event->message, event->message_length) + && bin_pack_u32(bp, event->message_id); +} + +non_null() +static bool tox_event_group_message_unpack( + Tox_Event_Group_Message *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 5)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && tox_unpack_message_type(bu, &event->type) + && bin_unpack_bin(bu, &event->message, &event->message_length) + && bin_unpack_u32(bu, &event->message_id); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Message *tox_events_add_group_message(Tox_Events *events) +{ + if (events->group_message_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_message_size == events->group_message_capacity) { + const uint32_t new_group_message_capacity = events->group_message_capacity * 2 + 1; + Tox_Event_Group_Message *new_group_message = (Tox_Event_Group_Message *) + realloc( + events->group_message, + new_group_message_capacity * sizeof(Tox_Event_Group_Message)); + + if (new_group_message == nullptr) { + return nullptr; + } + + events->group_message = new_group_message; + events->group_message_capacity = new_group_message_capacity; + } + + Tox_Event_Group_Message *const group_message = + &events->group_message[events->group_message_size]; + tox_event_group_message_construct(group_message); + ++events->group_message_size; + return group_message; +} + +void tox_events_clear_group_message(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_message_size; ++i) { + tox_event_group_message_destruct(&events->group_message[i]); + } + + free(events->group_message); + events->group_message = nullptr; + events->group_message_size = 0; + events->group_message_capacity = 0; +} + +uint32_t tox_events_get_group_message_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_message_size; +} + +const Tox_Event_Group_Message *tox_events_get_group_message(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_message_size); + assert(events->group_message != nullptr); + return &events->group_message[index]; +} + +bool tox_events_pack_group_message(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_message_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_message_pack(tox_events_get_group_message(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_message(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Message *event = tox_events_add_group_message(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_message_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_message(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, uint32_t message_id, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Message *group_message = tox_events_add_group_message(state->events); + + if (group_message == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_message_set_group_number(group_message, group_number); + tox_event_group_message_set_peer_id(group_message, peer_id); + tox_event_group_message_set_type(group_message, type); + tox_event_group_message_set_message(group_message, message, length); + tox_event_group_message_set_message_id(group_message, message_id); +} diff --git a/toxcore/events/group_moderation.c b/toxcore/events/group_moderation.c new file mode 100644 index 0000000000..5015994aaf --- /dev/null +++ b/toxcore/events/group_moderation.c @@ -0,0 +1,248 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Moderation { + uint32_t group_number; + uint32_t source_peer_id; + uint32_t target_peer_id; + Tox_Group_Mod_Event mod_type; +}; + +non_null() +static void tox_event_group_moderation_construct(Tox_Event_Group_Moderation *group_moderation) +{ + *group_moderation = (Tox_Event_Group_Moderation) { + 0 + }; +} +non_null() +static void tox_event_group_moderation_destruct(Tox_Event_Group_Moderation *group_moderation) +{ + return; +} + +non_null() +static void tox_event_group_moderation_set_group_number(Tox_Event_Group_Moderation *group_moderation, + uint32_t group_number) +{ + assert(group_moderation != nullptr); + group_moderation->group_number = group_number; +} +uint32_t tox_event_group_moderation_get_group_number(const Tox_Event_Group_Moderation *group_moderation) +{ + assert(group_moderation != nullptr); + return group_moderation->group_number; +} + +non_null() +static void tox_event_group_moderation_set_source_peer_id(Tox_Event_Group_Moderation *group_moderation, + uint32_t source_peer_id) +{ + assert(group_moderation != nullptr); + group_moderation->source_peer_id = source_peer_id; +} +uint32_t tox_event_group_moderation_get_source_peer_id(const Tox_Event_Group_Moderation *group_moderation) +{ + assert(group_moderation != nullptr); + return group_moderation->source_peer_id; +} + +non_null() +static void tox_event_group_moderation_set_target_peer_id(Tox_Event_Group_Moderation *group_moderation, + uint32_t target_peer_id) +{ + assert(group_moderation != nullptr); + group_moderation->target_peer_id = target_peer_id; +} +uint32_t tox_event_group_moderation_get_target_peer_id(const Tox_Event_Group_Moderation *group_moderation) +{ + assert(group_moderation != nullptr); + return group_moderation->target_peer_id; +} + +non_null() +static void tox_event_group_moderation_set_mod_type(Tox_Event_Group_Moderation *group_moderation, + Tox_Group_Mod_Event mod_type) +{ + assert(group_moderation != nullptr); + group_moderation->mod_type = mod_type; +} +Tox_Group_Mod_Event tox_event_group_moderation_get_mod_type(const Tox_Event_Group_Moderation *group_moderation) +{ + assert(group_moderation != nullptr); + return group_moderation->mod_type; +} + +non_null() +static bool tox_event_group_moderation_pack( + const Tox_Event_Group_Moderation *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_MODERATION) + && bin_pack_array(bp, 4) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->source_peer_id) + && bin_pack_u32(bp, event->target_peer_id) + && bin_pack_u32(bp, event->mod_type); +} + +non_null() +static bool tox_event_group_moderation_unpack( + Tox_Event_Group_Moderation *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 4)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->source_peer_id) + && bin_unpack_u32(bu, &event->target_peer_id) + && tox_unpack_group_mod_event(bu, &event->mod_type); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Moderation *tox_events_add_group_moderation(Tox_Events *events) +{ + if (events->group_moderation_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_moderation_size == events->group_moderation_capacity) { + const uint32_t new_group_moderation_capacity = events->group_moderation_capacity * 2 + 1; + Tox_Event_Group_Moderation *new_group_moderation = (Tox_Event_Group_Moderation *) + realloc( + events->group_moderation, + new_group_moderation_capacity * sizeof(Tox_Event_Group_Moderation)); + + if (new_group_moderation == nullptr) { + return nullptr; + } + + events->group_moderation = new_group_moderation; + events->group_moderation_capacity = new_group_moderation_capacity; + } + + Tox_Event_Group_Moderation *const group_moderation = + &events->group_moderation[events->group_moderation_size]; + tox_event_group_moderation_construct(group_moderation); + ++events->group_moderation_size; + return group_moderation; +} + +void tox_events_clear_group_moderation(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_moderation_size; ++i) { + tox_event_group_moderation_destruct(&events->group_moderation[i]); + } + + free(events->group_moderation); + events->group_moderation = nullptr; + events->group_moderation_size = 0; + events->group_moderation_capacity = 0; +} + +uint32_t tox_events_get_group_moderation_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_moderation_size; +} + +const Tox_Event_Group_Moderation *tox_events_get_group_moderation(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_moderation_size); + assert(events->group_moderation != nullptr); + return &events->group_moderation[index]; +} + +bool tox_events_pack_group_moderation(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_moderation_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_moderation_pack(tox_events_get_group_moderation(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_moderation(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Moderation *event = tox_events_add_group_moderation(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_moderation_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_moderation(Tox *tox, uint32_t group_number, uint32_t source_peer_id, uint32_t target_peer_id, Tox_Group_Mod_Event mod_type, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Moderation *group_moderation = tox_events_add_group_moderation(state->events); + + if (group_moderation == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_moderation_set_group_number(group_moderation, group_number); + tox_event_group_moderation_set_source_peer_id(group_moderation, source_peer_id); + tox_event_group_moderation_set_target_peer_id(group_moderation, target_peer_id); + tox_event_group_moderation_set_mod_type(group_moderation, mod_type); +} diff --git a/toxcore/events/group_password.c b/toxcore/events/group_password.c new file mode 100644 index 0000000000..45b2650bd2 --- /dev/null +++ b/toxcore/events/group_password.c @@ -0,0 +1,235 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Password { + uint32_t group_number; + uint8_t *password; + uint32_t password_length; +}; + +non_null() +static void tox_event_group_password_construct(Tox_Event_Group_Password *group_password) +{ + *group_password = (Tox_Event_Group_Password) { + 0 + }; +} +non_null() +static void tox_event_group_password_destruct(Tox_Event_Group_Password *group_password) +{ + free(group_password->password); +} + +non_null() +static void tox_event_group_password_set_group_number(Tox_Event_Group_Password *group_password, + uint32_t group_number) +{ + assert(group_password != nullptr); + group_password->group_number = group_number; +} +uint32_t tox_event_group_password_get_group_number(const Tox_Event_Group_Password *group_password) +{ + assert(group_password != nullptr); + return group_password->group_number; +} + +non_null() +static bool tox_event_group_password_set_password(Tox_Event_Group_Password *group_password, + const uint8_t *password, uint32_t password_length) +{ + assert(group_password != nullptr); + + if (group_password->password != nullptr) { + free(group_password->password); + group_password->password = nullptr; + group_password->password_length = 0; + } + + group_password->password = (uint8_t *)malloc(password_length); + + if (group_password->password == nullptr) { + return false; + } + + memcpy(group_password->password, password, password_length); + group_password->password_length = password_length; + return true; +} +size_t tox_event_group_password_get_password_length(const Tox_Event_Group_Password *group_password) +{ + assert(group_password != nullptr); + return group_password->password_length; +} +const uint8_t *tox_event_group_password_get_password(const Tox_Event_Group_Password *group_password) +{ + assert(group_password != nullptr); + return group_password->password; +} + +non_null() +static bool tox_event_group_password_pack( + const Tox_Event_Group_Password *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PASSWORD) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_bin(bp, event->password, event->password_length); +} + +non_null() +static bool tox_event_group_password_unpack( + Tox_Event_Group_Password *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_bin(bu, &event->password, &event->password_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Password *tox_events_add_group_password(Tox_Events *events) +{ + if (events->group_password_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_password_size == events->group_password_capacity) { + const uint32_t new_group_password_capacity = events->group_password_capacity * 2 + 1; + Tox_Event_Group_Password *new_group_password = (Tox_Event_Group_Password *) + realloc( + events->group_password, + new_group_password_capacity * sizeof(Tox_Event_Group_Password)); + + if (new_group_password == nullptr) { + return nullptr; + } + + events->group_password = new_group_password; + events->group_password_capacity = new_group_password_capacity; + } + + Tox_Event_Group_Password *const group_password = + &events->group_password[events->group_password_size]; + tox_event_group_password_construct(group_password); + ++events->group_password_size; + return group_password; +} + +void tox_events_clear_group_password(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_password_size; ++i) { + tox_event_group_password_destruct(&events->group_password[i]); + } + + free(events->group_password); + events->group_password = nullptr; + events->group_password_size = 0; + events->group_password_capacity = 0; +} + +uint32_t tox_events_get_group_password_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_password_size; +} + +const Tox_Event_Group_Password *tox_events_get_group_password(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_password_size); + assert(events->group_password != nullptr); + return &events->group_password[index]; +} + +bool tox_events_pack_group_password(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_password_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_password_pack(tox_events_get_group_password(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_password(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Password *event = tox_events_add_group_password(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_password_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_password(Tox *tox, uint32_t group_number, const uint8_t *password, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Password *group_password = tox_events_add_group_password(state->events); + + if (group_password == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_password_set_group_number(group_password, group_number); + tox_event_group_password_set_password(group_password, password, length); +} diff --git a/toxcore/events/group_peer_exit.c b/toxcore/events/group_peer_exit.c new file mode 100644 index 0000000000..20d11b2ef1 --- /dev/null +++ b/toxcore/events/group_peer_exit.c @@ -0,0 +1,308 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Peer_Exit { + uint32_t group_number; + uint32_t peer_id; + Tox_Group_Exit_Type exit_type; + uint8_t *name; + uint32_t name_length; + uint8_t *part_message; + uint32_t part_message_length; +}; + +non_null() +static void tox_event_group_peer_exit_construct(Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + *group_peer_exit = (Tox_Event_Group_Peer_Exit) { + 0 + }; +} +non_null() +static void tox_event_group_peer_exit_destruct(Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + free(group_peer_exit->name); + free(group_peer_exit->part_message); +} + +non_null() +static void tox_event_group_peer_exit_set_group_number(Tox_Event_Group_Peer_Exit *group_peer_exit, + uint32_t group_number) +{ + assert(group_peer_exit != nullptr); + group_peer_exit->group_number = group_number; +} +uint32_t tox_event_group_peer_exit_get_group_number(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->group_number; +} + +non_null() +static void tox_event_group_peer_exit_set_peer_id(Tox_Event_Group_Peer_Exit *group_peer_exit, + uint32_t peer_id) +{ + assert(group_peer_exit != nullptr); + group_peer_exit->peer_id = peer_id; +} +uint32_t tox_event_group_peer_exit_get_peer_id(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->peer_id; +} + +non_null() +static void tox_event_group_peer_exit_set_exit_type(Tox_Event_Group_Peer_Exit *group_peer_exit, + Tox_Group_Exit_Type exit_type) +{ + assert(group_peer_exit != nullptr); + group_peer_exit->exit_type = exit_type; +} +Tox_Group_Exit_Type tox_event_group_peer_exit_get_exit_type(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->exit_type; +} + +non_null() +static bool tox_event_group_peer_exit_set_name(Tox_Event_Group_Peer_Exit *group_peer_exit, + const uint8_t *name, uint32_t name_length) +{ + assert(group_peer_exit != nullptr); + + if (group_peer_exit->name != nullptr) { + free(group_peer_exit->name); + group_peer_exit->name = nullptr; + group_peer_exit->name_length = 0; + } + + group_peer_exit->name = (uint8_t *)malloc(name_length); + + if (group_peer_exit->name == nullptr) { + return false; + } + + memcpy(group_peer_exit->name, name, name_length); + group_peer_exit->name_length = name_length; + return true; +} +size_t tox_event_group_peer_exit_get_name_length(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->name_length; +} +const uint8_t *tox_event_group_peer_exit_get_name(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->name; +} + +non_null() +static bool tox_event_group_peer_exit_set_part_message(Tox_Event_Group_Peer_Exit *group_peer_exit, + const uint8_t *part_message, uint32_t part_message_length) +{ + assert(group_peer_exit != nullptr); + + if (group_peer_exit->part_message != nullptr) { + free(group_peer_exit->part_message); + group_peer_exit->part_message = nullptr; + group_peer_exit->part_message_length = 0; + } + + group_peer_exit->part_message = (uint8_t *)malloc(part_message_length); + + if (group_peer_exit->part_message == nullptr) { + return false; + } + + memcpy(group_peer_exit->part_message, part_message, part_message_length); + group_peer_exit->part_message_length = part_message_length; + return true; +} +size_t tox_event_group_peer_exit_get_part_message_length(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->part_message_length; +} +const uint8_t *tox_event_group_peer_exit_get_part_message(const Tox_Event_Group_Peer_Exit *group_peer_exit) +{ + assert(group_peer_exit != nullptr); + return group_peer_exit->part_message; +} + +non_null() +static bool tox_event_group_peer_exit_pack( + const Tox_Event_Group_Peer_Exit *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PEER_EXIT) + && bin_pack_array(bp, 5) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_u32(bp, event->exit_type) + && bin_pack_bin(bp, event->name, event->name_length) + && bin_pack_bin(bp, event->part_message, event->part_message_length); +} + +non_null() +static bool tox_event_group_peer_exit_unpack( + Tox_Event_Group_Peer_Exit *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 5)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && tox_unpack_group_exit_type(bu, &event->exit_type) + && bin_unpack_bin(bu, &event->name, &event->name_length) + && bin_unpack_bin(bu, &event->part_message, &event->part_message_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Peer_Exit *tox_events_add_group_peer_exit(Tox_Events *events) +{ + if (events->group_peer_exit_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_peer_exit_size == events->group_peer_exit_capacity) { + const uint32_t new_group_peer_exit_capacity = events->group_peer_exit_capacity * 2 + 1; + Tox_Event_Group_Peer_Exit *new_group_peer_exit = (Tox_Event_Group_Peer_Exit *) + realloc( + events->group_peer_exit, + new_group_peer_exit_capacity * sizeof(Tox_Event_Group_Peer_Exit)); + + if (new_group_peer_exit == nullptr) { + return nullptr; + } + + events->group_peer_exit = new_group_peer_exit; + events->group_peer_exit_capacity = new_group_peer_exit_capacity; + } + + Tox_Event_Group_Peer_Exit *const group_peer_exit = + &events->group_peer_exit[events->group_peer_exit_size]; + tox_event_group_peer_exit_construct(group_peer_exit); + ++events->group_peer_exit_size; + return group_peer_exit; +} + +void tox_events_clear_group_peer_exit(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_peer_exit_size; ++i) { + tox_event_group_peer_exit_destruct(&events->group_peer_exit[i]); + } + + free(events->group_peer_exit); + events->group_peer_exit = nullptr; + events->group_peer_exit_size = 0; + events->group_peer_exit_capacity = 0; +} + +uint32_t tox_events_get_group_peer_exit_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_peer_exit_size; +} + +const Tox_Event_Group_Peer_Exit *tox_events_get_group_peer_exit(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_peer_exit_size); + assert(events->group_peer_exit != nullptr); + return &events->group_peer_exit[index]; +} + +bool tox_events_pack_group_peer_exit(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_peer_exit_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_peer_exit_pack(tox_events_get_group_peer_exit(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_peer_exit(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Peer_Exit *event = tox_events_add_group_peer_exit(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_peer_exit_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_peer_exit(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Group_Exit_Type exit_type, const uint8_t *name, size_t name_length, const uint8_t *part_message, size_t part_message_length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Peer_Exit *group_peer_exit = tox_events_add_group_peer_exit(state->events); + + if (group_peer_exit == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_peer_exit_set_group_number(group_peer_exit, group_number); + tox_event_group_peer_exit_set_peer_id(group_peer_exit, peer_id); + tox_event_group_peer_exit_set_exit_type(group_peer_exit, exit_type); + tox_event_group_peer_exit_set_name(group_peer_exit, name, name_length); + tox_event_group_peer_exit_set_part_message(group_peer_exit, part_message, part_message_length); +} diff --git a/toxcore/events/group_peer_join.c b/toxcore/events/group_peer_join.c new file mode 100644 index 0000000000..cff0e6802d --- /dev/null +++ b/toxcore/events/group_peer_join.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Peer_Join { + uint32_t group_number; + uint32_t peer_id; +}; + +non_null() +static void tox_event_group_peer_join_construct(Tox_Event_Group_Peer_Join *group_peer_join) +{ + *group_peer_join = (Tox_Event_Group_Peer_Join) { + 0 + }; +} +non_null() +static void tox_event_group_peer_join_destruct(Tox_Event_Group_Peer_Join *group_peer_join) +{ + return; +} + +non_null() +static void tox_event_group_peer_join_set_group_number(Tox_Event_Group_Peer_Join *group_peer_join, + uint32_t group_number) +{ + assert(group_peer_join != nullptr); + group_peer_join->group_number = group_number; +} +uint32_t tox_event_group_peer_join_get_group_number(const Tox_Event_Group_Peer_Join *group_peer_join) +{ + assert(group_peer_join != nullptr); + return group_peer_join->group_number; +} + +non_null() +static void tox_event_group_peer_join_set_peer_id(Tox_Event_Group_Peer_Join *group_peer_join, + uint32_t peer_id) +{ + assert(group_peer_join != nullptr); + group_peer_join->peer_id = peer_id; +} +uint32_t tox_event_group_peer_join_get_peer_id(const Tox_Event_Group_Peer_Join *group_peer_join) +{ + assert(group_peer_join != nullptr); + return group_peer_join->peer_id; +} + +non_null() +static bool tox_event_group_peer_join_pack( + const Tox_Event_Group_Peer_Join *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PEER_JOIN) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id); +} + +non_null() +static bool tox_event_group_peer_join_unpack( + Tox_Event_Group_Peer_Join *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Peer_Join *tox_events_add_group_peer_join(Tox_Events *events) +{ + if (events->group_peer_join_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_peer_join_size == events->group_peer_join_capacity) { + const uint32_t new_group_peer_join_capacity = events->group_peer_join_capacity * 2 + 1; + Tox_Event_Group_Peer_Join *new_group_peer_join = (Tox_Event_Group_Peer_Join *) + realloc( + events->group_peer_join, + new_group_peer_join_capacity * sizeof(Tox_Event_Group_Peer_Join)); + + if (new_group_peer_join == nullptr) { + return nullptr; + } + + events->group_peer_join = new_group_peer_join; + events->group_peer_join_capacity = new_group_peer_join_capacity; + } + + Tox_Event_Group_Peer_Join *const group_peer_join = + &events->group_peer_join[events->group_peer_join_size]; + tox_event_group_peer_join_construct(group_peer_join); + ++events->group_peer_join_size; + return group_peer_join; +} + +void tox_events_clear_group_peer_join(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_peer_join_size; ++i) { + tox_event_group_peer_join_destruct(&events->group_peer_join[i]); + } + + free(events->group_peer_join); + events->group_peer_join = nullptr; + events->group_peer_join_size = 0; + events->group_peer_join_capacity = 0; +} + +uint32_t tox_events_get_group_peer_join_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_peer_join_size; +} + +const Tox_Event_Group_Peer_Join *tox_events_get_group_peer_join(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_peer_join_size); + assert(events->group_peer_join != nullptr); + return &events->group_peer_join[index]; +} + +bool tox_events_pack_group_peer_join(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_peer_join_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_peer_join_pack(tox_events_get_group_peer_join(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_peer_join(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Peer_Join *event = tox_events_add_group_peer_join(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_peer_join_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_peer_join(Tox *tox, uint32_t group_number, uint32_t peer_id, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Peer_Join *group_peer_join = tox_events_add_group_peer_join(state->events); + + if (group_peer_join == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_peer_join_set_group_number(group_peer_join, group_number); + tox_event_group_peer_join_set_peer_id(group_peer_join, peer_id); +} diff --git a/toxcore/events/group_peer_limit.c b/toxcore/events/group_peer_limit.c new file mode 100644 index 0000000000..0cdf6c41bd --- /dev/null +++ b/toxcore/events/group_peer_limit.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Peer_Limit { + uint32_t group_number; + uint32_t peer_limit; +}; + +non_null() +static void tox_event_group_peer_limit_construct(Tox_Event_Group_Peer_Limit *group_peer_limit) +{ + *group_peer_limit = (Tox_Event_Group_Peer_Limit) { + 0 + }; +} +non_null() +static void tox_event_group_peer_limit_destruct(Tox_Event_Group_Peer_Limit *group_peer_limit) +{ + return; +} + +non_null() +static void tox_event_group_peer_limit_set_group_number(Tox_Event_Group_Peer_Limit *group_peer_limit, + uint32_t group_number) +{ + assert(group_peer_limit != nullptr); + group_peer_limit->group_number = group_number; +} +uint32_t tox_event_group_peer_limit_get_group_number(const Tox_Event_Group_Peer_Limit *group_peer_limit) +{ + assert(group_peer_limit != nullptr); + return group_peer_limit->group_number; +} + +non_null() +static void tox_event_group_peer_limit_set_peer_limit(Tox_Event_Group_Peer_Limit *group_peer_limit, + uint32_t peer_limit) +{ + assert(group_peer_limit != nullptr); + group_peer_limit->peer_limit = peer_limit; +} +uint32_t tox_event_group_peer_limit_get_peer_limit(const Tox_Event_Group_Peer_Limit *group_peer_limit) +{ + assert(group_peer_limit != nullptr); + return group_peer_limit->peer_limit; +} + +non_null() +static bool tox_event_group_peer_limit_pack( + const Tox_Event_Group_Peer_Limit *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PEER_LIMIT) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_limit); +} + +non_null() +static bool tox_event_group_peer_limit_unpack( + Tox_Event_Group_Peer_Limit *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_limit); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Peer_Limit *tox_events_add_group_peer_limit(Tox_Events *events) +{ + if (events->group_peer_limit_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_peer_limit_size == events->group_peer_limit_capacity) { + const uint32_t new_group_peer_limit_capacity = events->group_peer_limit_capacity * 2 + 1; + Tox_Event_Group_Peer_Limit *new_group_peer_limit = (Tox_Event_Group_Peer_Limit *) + realloc( + events->group_peer_limit, + new_group_peer_limit_capacity * sizeof(Tox_Event_Group_Peer_Limit)); + + if (new_group_peer_limit == nullptr) { + return nullptr; + } + + events->group_peer_limit = new_group_peer_limit; + events->group_peer_limit_capacity = new_group_peer_limit_capacity; + } + + Tox_Event_Group_Peer_Limit *const group_peer_limit = + &events->group_peer_limit[events->group_peer_limit_size]; + tox_event_group_peer_limit_construct(group_peer_limit); + ++events->group_peer_limit_size; + return group_peer_limit; +} + +void tox_events_clear_group_peer_limit(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_peer_limit_size; ++i) { + tox_event_group_peer_limit_destruct(&events->group_peer_limit[i]); + } + + free(events->group_peer_limit); + events->group_peer_limit = nullptr; + events->group_peer_limit_size = 0; + events->group_peer_limit_capacity = 0; +} + +uint32_t tox_events_get_group_peer_limit_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_peer_limit_size; +} + +const Tox_Event_Group_Peer_Limit *tox_events_get_group_peer_limit(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_peer_limit_size); + assert(events->group_peer_limit != nullptr); + return &events->group_peer_limit[index]; +} + +bool tox_events_pack_group_peer_limit(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_peer_limit_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_peer_limit_pack(tox_events_get_group_peer_limit(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_peer_limit(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Peer_Limit *event = tox_events_add_group_peer_limit(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_peer_limit_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_peer_limit(Tox *tox, uint32_t group_number, uint32_t peer_limit, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Peer_Limit *group_peer_limit = tox_events_add_group_peer_limit(state->events); + + if (group_peer_limit == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_peer_limit_set_group_number(group_peer_limit, group_number); + tox_event_group_peer_limit_set_peer_limit(group_peer_limit, peer_limit); +} diff --git a/toxcore/events/group_peer_name.c b/toxcore/events/group_peer_name.c new file mode 100644 index 0000000000..b5eb859d35 --- /dev/null +++ b/toxcore/events/group_peer_name.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Peer_Name { + uint32_t group_number; + uint32_t peer_id; + uint8_t *name; + uint32_t name_length; +}; + +non_null() +static void tox_event_group_peer_name_construct(Tox_Event_Group_Peer_Name *group_peer_name) +{ + *group_peer_name = (Tox_Event_Group_Peer_Name) { + 0 + }; +} +non_null() +static void tox_event_group_peer_name_destruct(Tox_Event_Group_Peer_Name *group_peer_name) +{ + free(group_peer_name->name); +} + +non_null() +static void tox_event_group_peer_name_set_group_number(Tox_Event_Group_Peer_Name *group_peer_name, + uint32_t group_number) +{ + assert(group_peer_name != nullptr); + group_peer_name->group_number = group_number; +} +uint32_t tox_event_group_peer_name_get_group_number(const Tox_Event_Group_Peer_Name *group_peer_name) +{ + assert(group_peer_name != nullptr); + return group_peer_name->group_number; +} + +non_null() +static void tox_event_group_peer_name_set_peer_id(Tox_Event_Group_Peer_Name *group_peer_name, + uint32_t peer_id) +{ + assert(group_peer_name != nullptr); + group_peer_name->peer_id = peer_id; +} +uint32_t tox_event_group_peer_name_get_peer_id(const Tox_Event_Group_Peer_Name *group_peer_name) +{ + assert(group_peer_name != nullptr); + return group_peer_name->peer_id; +} + +non_null() +static bool tox_event_group_peer_name_set_name(Tox_Event_Group_Peer_Name *group_peer_name, + const uint8_t *name, uint32_t name_length) +{ + assert(group_peer_name != nullptr); + + if (group_peer_name->name != nullptr) { + free(group_peer_name->name); + group_peer_name->name = nullptr; + group_peer_name->name_length = 0; + } + + group_peer_name->name = (uint8_t *)malloc(name_length); + + if (group_peer_name->name == nullptr) { + return false; + } + + memcpy(group_peer_name->name, name, name_length); + group_peer_name->name_length = name_length; + return true; +} +size_t tox_event_group_peer_name_get_name_length(const Tox_Event_Group_Peer_Name *group_peer_name) +{ + assert(group_peer_name != nullptr); + return group_peer_name->name_length; +} +const uint8_t *tox_event_group_peer_name_get_name(const Tox_Event_Group_Peer_Name *group_peer_name) +{ + assert(group_peer_name != nullptr); + return group_peer_name->name; +} + +non_null() +static bool tox_event_group_peer_name_pack( + const Tox_Event_Group_Peer_Name *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PEER_NAME) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_bin(bp, event->name, event->name_length); +} + +non_null() +static bool tox_event_group_peer_name_unpack( + Tox_Event_Group_Peer_Name *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && bin_unpack_bin(bu, &event->name, &event->name_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Peer_Name *tox_events_add_group_peer_name(Tox_Events *events) +{ + if (events->group_peer_name_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_peer_name_size == events->group_peer_name_capacity) { + const uint32_t new_group_peer_name_capacity = events->group_peer_name_capacity * 2 + 1; + Tox_Event_Group_Peer_Name *new_group_peer_name = (Tox_Event_Group_Peer_Name *) + realloc( + events->group_peer_name, + new_group_peer_name_capacity * sizeof(Tox_Event_Group_Peer_Name)); + + if (new_group_peer_name == nullptr) { + return nullptr; + } + + events->group_peer_name = new_group_peer_name; + events->group_peer_name_capacity = new_group_peer_name_capacity; + } + + Tox_Event_Group_Peer_Name *const group_peer_name = + &events->group_peer_name[events->group_peer_name_size]; + tox_event_group_peer_name_construct(group_peer_name); + ++events->group_peer_name_size; + return group_peer_name; +} + +void tox_events_clear_group_peer_name(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_peer_name_size; ++i) { + tox_event_group_peer_name_destruct(&events->group_peer_name[i]); + } + + free(events->group_peer_name); + events->group_peer_name = nullptr; + events->group_peer_name_size = 0; + events->group_peer_name_capacity = 0; +} + +uint32_t tox_events_get_group_peer_name_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_peer_name_size; +} + +const Tox_Event_Group_Peer_Name *tox_events_get_group_peer_name(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_peer_name_size); + assert(events->group_peer_name != nullptr); + return &events->group_peer_name[index]; +} + +bool tox_events_pack_group_peer_name(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_peer_name_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_peer_name_pack(tox_events_get_group_peer_name(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_peer_name(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Peer_Name *event = tox_events_add_group_peer_name(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_peer_name_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_peer_name(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *name, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Peer_Name *group_peer_name = tox_events_add_group_peer_name(state->events); + + if (group_peer_name == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_peer_name_set_group_number(group_peer_name, group_number); + tox_event_group_peer_name_set_peer_id(group_peer_name, peer_id); + tox_event_group_peer_name_set_name(group_peer_name, name, length); +} diff --git a/toxcore/events/group_peer_status.c b/toxcore/events/group_peer_status.c new file mode 100644 index 0000000000..b5e63b6639 --- /dev/null +++ b/toxcore/events/group_peer_status.c @@ -0,0 +1,231 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Peer_Status { + uint32_t group_number; + uint32_t peer_id; + Tox_User_Status status; +}; + +non_null() +static void tox_event_group_peer_status_construct(Tox_Event_Group_Peer_Status *group_peer_status) +{ + *group_peer_status = (Tox_Event_Group_Peer_Status) { + 0 + }; +} +non_null() +static void tox_event_group_peer_status_destruct(Tox_Event_Group_Peer_Status *group_peer_status) +{ + return; +} + +non_null() +static void tox_event_group_peer_status_set_group_number(Tox_Event_Group_Peer_Status *group_peer_status, + uint32_t group_number) +{ + assert(group_peer_status != nullptr); + group_peer_status->group_number = group_number; +} +uint32_t tox_event_group_peer_status_get_group_number(const Tox_Event_Group_Peer_Status *group_peer_status) +{ + assert(group_peer_status != nullptr); + return group_peer_status->group_number; +} + +non_null() +static void tox_event_group_peer_status_set_peer_id(Tox_Event_Group_Peer_Status *group_peer_status, + uint32_t peer_id) +{ + assert(group_peer_status != nullptr); + group_peer_status->peer_id = peer_id; +} +uint32_t tox_event_group_peer_status_get_peer_id(const Tox_Event_Group_Peer_Status *group_peer_status) +{ + assert(group_peer_status != nullptr); + return group_peer_status->peer_id; +} + +non_null() +static void tox_event_group_peer_status_set_status(Tox_Event_Group_Peer_Status *group_peer_status, + Tox_User_Status status) +{ + assert(group_peer_status != nullptr); + group_peer_status->status = status; +} +Tox_User_Status tox_event_group_peer_status_get_status(const Tox_Event_Group_Peer_Status *group_peer_status) +{ + assert(group_peer_status != nullptr); + return group_peer_status->status; +} + +non_null() +static bool tox_event_group_peer_status_pack( + const Tox_Event_Group_Peer_Status *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PEER_STATUS) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_u32(bp, event->status); +} + +non_null() +static bool tox_event_group_peer_status_unpack( + Tox_Event_Group_Peer_Status *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && tox_unpack_user_status(bu, &event->status); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Peer_Status *tox_events_add_group_peer_status(Tox_Events *events) +{ + if (events->group_peer_status_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_peer_status_size == events->group_peer_status_capacity) { + const uint32_t new_group_peer_status_capacity = events->group_peer_status_capacity * 2 + 1; + Tox_Event_Group_Peer_Status *new_group_peer_status = (Tox_Event_Group_Peer_Status *) + realloc( + events->group_peer_status, + new_group_peer_status_capacity * sizeof(Tox_Event_Group_Peer_Status)); + + if (new_group_peer_status == nullptr) { + return nullptr; + } + + events->group_peer_status = new_group_peer_status; + events->group_peer_status_capacity = new_group_peer_status_capacity; + } + + Tox_Event_Group_Peer_Status *const group_peer_status = + &events->group_peer_status[events->group_peer_status_size]; + tox_event_group_peer_status_construct(group_peer_status); + ++events->group_peer_status_size; + return group_peer_status; +} + +void tox_events_clear_group_peer_status(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_peer_status_size; ++i) { + tox_event_group_peer_status_destruct(&events->group_peer_status[i]); + } + + free(events->group_peer_status); + events->group_peer_status = nullptr; + events->group_peer_status_size = 0; + events->group_peer_status_capacity = 0; +} + +uint32_t tox_events_get_group_peer_status_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_peer_status_size; +} + +const Tox_Event_Group_Peer_Status *tox_events_get_group_peer_status(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_peer_status_size); + assert(events->group_peer_status != nullptr); + return &events->group_peer_status[index]; +} + +bool tox_events_pack_group_peer_status(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_peer_status_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_peer_status_pack(tox_events_get_group_peer_status(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_peer_status(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Peer_Status *event = tox_events_add_group_peer_status(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_peer_status_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_peer_status(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_User_Status status, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Peer_Status *group_peer_status = tox_events_add_group_peer_status(state->events); + + if (group_peer_status == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_peer_status_set_group_number(group_peer_status, group_number); + tox_event_group_peer_status_set_peer_id(group_peer_status, peer_id); + tox_event_group_peer_status_set_status(group_peer_status, status); +} diff --git a/toxcore/events/group_privacy_state.c b/toxcore/events/group_privacy_state.c new file mode 100644 index 0000000000..caa00f0367 --- /dev/null +++ b/toxcore/events/group_privacy_state.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Privacy_State { + uint32_t group_number; + Tox_Group_Privacy_State privacy_state; +}; + +non_null() +static void tox_event_group_privacy_state_construct(Tox_Event_Group_Privacy_State *group_privacy_state) +{ + *group_privacy_state = (Tox_Event_Group_Privacy_State) { + 0 + }; +} +non_null() +static void tox_event_group_privacy_state_destruct(Tox_Event_Group_Privacy_State *group_privacy_state) +{ + return; +} + +non_null() +static void tox_event_group_privacy_state_set_group_number(Tox_Event_Group_Privacy_State *group_privacy_state, + uint32_t group_number) +{ + assert(group_privacy_state != nullptr); + group_privacy_state->group_number = group_number; +} +uint32_t tox_event_group_privacy_state_get_group_number(const Tox_Event_Group_Privacy_State *group_privacy_state) +{ + assert(group_privacy_state != nullptr); + return group_privacy_state->group_number; +} + +non_null() +static void tox_event_group_privacy_state_set_privacy_state(Tox_Event_Group_Privacy_State *group_privacy_state, + Tox_Group_Privacy_State privacy_state) +{ + assert(group_privacy_state != nullptr); + group_privacy_state->privacy_state = privacy_state; +} +Tox_Group_Privacy_State tox_event_group_privacy_state_get_privacy_state(const Tox_Event_Group_Privacy_State *group_privacy_state) +{ + assert(group_privacy_state != nullptr); + return group_privacy_state->privacy_state; +} + +non_null() +static bool tox_event_group_privacy_state_pack( + const Tox_Event_Group_Privacy_State *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PRIVACY_STATE) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->privacy_state); +} + +non_null() +static bool tox_event_group_privacy_state_unpack( + Tox_Event_Group_Privacy_State *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && tox_unpack_group_privacy_state(bu, &event->privacy_state); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Privacy_State *tox_events_add_group_privacy_state(Tox_Events *events) +{ + if (events->group_privacy_state_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_privacy_state_size == events->group_privacy_state_capacity) { + const uint32_t new_group_privacy_state_capacity = events->group_privacy_state_capacity * 2 + 1; + Tox_Event_Group_Privacy_State *new_group_privacy_state = (Tox_Event_Group_Privacy_State *) + realloc( + events->group_privacy_state, + new_group_privacy_state_capacity * sizeof(Tox_Event_Group_Privacy_State)); + + if (new_group_privacy_state == nullptr) { + return nullptr; + } + + events->group_privacy_state = new_group_privacy_state; + events->group_privacy_state_capacity = new_group_privacy_state_capacity; + } + + Tox_Event_Group_Privacy_State *const group_privacy_state = + &events->group_privacy_state[events->group_privacy_state_size]; + tox_event_group_privacy_state_construct(group_privacy_state); + ++events->group_privacy_state_size; + return group_privacy_state; +} + +void tox_events_clear_group_privacy_state(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_privacy_state_size; ++i) { + tox_event_group_privacy_state_destruct(&events->group_privacy_state[i]); + } + + free(events->group_privacy_state); + events->group_privacy_state = nullptr; + events->group_privacy_state_size = 0; + events->group_privacy_state_capacity = 0; +} + +uint32_t tox_events_get_group_privacy_state_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_privacy_state_size; +} + +const Tox_Event_Group_Privacy_State *tox_events_get_group_privacy_state(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_privacy_state_size); + assert(events->group_privacy_state != nullptr); + return &events->group_privacy_state[index]; +} + +bool tox_events_pack_group_privacy_state(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_privacy_state_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_privacy_state_pack(tox_events_get_group_privacy_state(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_privacy_state(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Privacy_State *event = tox_events_add_group_privacy_state(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_privacy_state_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_privacy_state(Tox *tox, uint32_t group_number, Tox_Group_Privacy_State privacy_state, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Privacy_State *group_privacy_state = tox_events_add_group_privacy_state(state->events); + + if (group_privacy_state == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_privacy_state_set_group_number(group_privacy_state, group_number); + tox_event_group_privacy_state_set_privacy_state(group_privacy_state, privacy_state); +} diff --git a/toxcore/events/group_private_message.c b/toxcore/events/group_private_message.c new file mode 100644 index 0000000000..f5af54a4fc --- /dev/null +++ b/toxcore/events/group_private_message.c @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Private_Message { + uint32_t group_number; + uint32_t peer_id; + Tox_Message_Type type; + uint8_t *message; + uint32_t message_length; +}; + +non_null() +static void tox_event_group_private_message_construct(Tox_Event_Group_Private_Message *group_private_message) +{ + *group_private_message = (Tox_Event_Group_Private_Message) { + 0 + }; +} +non_null() +static void tox_event_group_private_message_destruct(Tox_Event_Group_Private_Message *group_private_message) +{ + free(group_private_message->message); +} + +non_null() +static void tox_event_group_private_message_set_group_number(Tox_Event_Group_Private_Message *group_private_message, + uint32_t group_number) +{ + assert(group_private_message != nullptr); + group_private_message->group_number = group_number; +} +uint32_t tox_event_group_private_message_get_group_number(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->group_number; +} + +non_null() +static void tox_event_group_private_message_set_peer_id(Tox_Event_Group_Private_Message *group_private_message, + uint32_t peer_id) +{ + assert(group_private_message != nullptr); + group_private_message->peer_id = peer_id; +} +uint32_t tox_event_group_private_message_get_peer_id(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->peer_id; +} + +non_null() +static void tox_event_group_private_message_set_type(Tox_Event_Group_Private_Message *group_private_message, + Tox_Message_Type type) +{ + assert(group_private_message != nullptr); + group_private_message->type = type; +} +Tox_Message_Type tox_event_group_private_message_get_type(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->type; +} + +non_null() +static bool tox_event_group_private_message_set_message(Tox_Event_Group_Private_Message *group_private_message, + const uint8_t *message, uint32_t message_length) +{ + assert(group_private_message != nullptr); + + if (group_private_message->message != nullptr) { + free(group_private_message->message); + group_private_message->message = nullptr; + group_private_message->message_length = 0; + } + + group_private_message->message = (uint8_t *)malloc(message_length); + + if (group_private_message->message == nullptr) { + return false; + } + + memcpy(group_private_message->message, message, message_length); + group_private_message->message_length = message_length; + return true; +} +size_t tox_event_group_private_message_get_message_length(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->message_length; +} +const uint8_t *tox_event_group_private_message_get_message(const Tox_Event_Group_Private_Message *group_private_message) +{ + assert(group_private_message != nullptr); + return group_private_message->message; +} + +non_null() +static bool tox_event_group_private_message_pack( + const Tox_Event_Group_Private_Message *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_PRIVATE_MESSAGE) + && bin_pack_array(bp, 4) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_u32(bp, event->type) + && bin_pack_bin(bp, event->message, event->message_length); +} + +non_null() +static bool tox_event_group_private_message_unpack( + Tox_Event_Group_Private_Message *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 4)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && tox_unpack_message_type(bu, &event->type) + && bin_unpack_bin(bu, &event->message, &event->message_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Private_Message *tox_events_add_group_private_message(Tox_Events *events) +{ + if (events->group_private_message_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_private_message_size == events->group_private_message_capacity) { + const uint32_t new_group_private_message_capacity = events->group_private_message_capacity * 2 + 1; + Tox_Event_Group_Private_Message *new_group_private_message = (Tox_Event_Group_Private_Message *) + realloc( + events->group_private_message, + new_group_private_message_capacity * sizeof(Tox_Event_Group_Private_Message)); + + if (new_group_private_message == nullptr) { + return nullptr; + } + + events->group_private_message = new_group_private_message; + events->group_private_message_capacity = new_group_private_message_capacity; + } + + Tox_Event_Group_Private_Message *const group_private_message = + &events->group_private_message[events->group_private_message_size]; + tox_event_group_private_message_construct(group_private_message); + ++events->group_private_message_size; + return group_private_message; +} + +void tox_events_clear_group_private_message(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_private_message_size; ++i) { + tox_event_group_private_message_destruct(&events->group_private_message[i]); + } + + free(events->group_private_message); + events->group_private_message = nullptr; + events->group_private_message_size = 0; + events->group_private_message_capacity = 0; +} + +uint32_t tox_events_get_group_private_message_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_private_message_size; +} + +const Tox_Event_Group_Private_Message *tox_events_get_group_private_message(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_private_message_size); + assert(events->group_private_message != nullptr); + return &events->group_private_message[index]; +} + +bool tox_events_pack_group_private_message(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_private_message_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_private_message_pack(tox_events_get_group_private_message(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_private_message(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Private_Message *event = tox_events_add_group_private_message(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_private_message_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_private_message(Tox *tox, uint32_t group_number, uint32_t peer_id, Tox_Message_Type type, const uint8_t *message, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Private_Message *group_private_message = tox_events_add_group_private_message(state->events); + + if (group_private_message == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_private_message_set_group_number(group_private_message, group_number); + tox_event_group_private_message_set_peer_id(group_private_message, peer_id); + tox_event_group_private_message_set_type(group_private_message, type); + tox_event_group_private_message_set_message(group_private_message, message, length); +} diff --git a/toxcore/events/group_self_join.c b/toxcore/events/group_self_join.c new file mode 100644 index 0000000000..c4f78d0ec2 --- /dev/null +++ b/toxcore/events/group_self_join.c @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Self_Join { + uint32_t group_number; +}; + +non_null() +static void tox_event_group_self_join_construct(Tox_Event_Group_Self_Join *group_self_join) +{ + *group_self_join = (Tox_Event_Group_Self_Join) { + 0 + }; +} +non_null() +static void tox_event_group_self_join_destruct(Tox_Event_Group_Self_Join *group_self_join) +{ + return; +} + +non_null() +static void tox_event_group_self_join_set_group_number(Tox_Event_Group_Self_Join *group_self_join, + uint32_t group_number) +{ + assert(group_self_join != nullptr); + group_self_join->group_number = group_number; +} +uint32_t tox_event_group_self_join_get_group_number(const Tox_Event_Group_Self_Join *group_self_join) +{ + assert(group_self_join != nullptr); + return group_self_join->group_number; +} + +non_null() +static bool tox_event_group_self_join_pack( + const Tox_Event_Group_Self_Join *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_SELF_JOIN) + + && bin_pack_u32(bp, event->group_number); +} + +non_null() +static bool tox_event_group_self_join_unpack( + Tox_Event_Group_Self_Join *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + return bin_unpack_u32(bu, &event->group_number); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Self_Join *tox_events_add_group_self_join(Tox_Events *events) +{ + if (events->group_self_join_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_self_join_size == events->group_self_join_capacity) { + const uint32_t new_group_self_join_capacity = events->group_self_join_capacity * 2 + 1; + Tox_Event_Group_Self_Join *new_group_self_join = (Tox_Event_Group_Self_Join *) + realloc( + events->group_self_join, + new_group_self_join_capacity * sizeof(Tox_Event_Group_Self_Join)); + + if (new_group_self_join == nullptr) { + return nullptr; + } + + events->group_self_join = new_group_self_join; + events->group_self_join_capacity = new_group_self_join_capacity; + } + + Tox_Event_Group_Self_Join *const group_self_join = + &events->group_self_join[events->group_self_join_size]; + tox_event_group_self_join_construct(group_self_join); + ++events->group_self_join_size; + return group_self_join; +} + +void tox_events_clear_group_self_join(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_self_join_size; ++i) { + tox_event_group_self_join_destruct(&events->group_self_join[i]); + } + + free(events->group_self_join); + events->group_self_join = nullptr; + events->group_self_join_size = 0; + events->group_self_join_capacity = 0; +} + +uint32_t tox_events_get_group_self_join_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_self_join_size; +} + +const Tox_Event_Group_Self_Join *tox_events_get_group_self_join(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_self_join_size); + assert(events->group_self_join != nullptr); + return &events->group_self_join[index]; +} + +bool tox_events_pack_group_self_join(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_self_join_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_self_join_pack(tox_events_get_group_self_join(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_self_join(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Self_Join *event = tox_events_add_group_self_join(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_self_join_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_self_join(Tox *tox, uint32_t group_number, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Self_Join *group_self_join = tox_events_add_group_self_join(state->events); + + if (group_self_join == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_self_join_set_group_number(group_self_join, group_number); +} diff --git a/toxcore/events/group_topic.c b/toxcore/events/group_topic.c new file mode 100644 index 0000000000..c9d815231b --- /dev/null +++ b/toxcore/events/group_topic.c @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Topic { + uint32_t group_number; + uint32_t peer_id; + uint8_t *topic; + uint32_t topic_length; +}; + +non_null() +static void tox_event_group_topic_construct(Tox_Event_Group_Topic *group_topic) +{ + *group_topic = (Tox_Event_Group_Topic) { + 0 + }; +} +non_null() +static void tox_event_group_topic_destruct(Tox_Event_Group_Topic *group_topic) +{ + free(group_topic->topic); +} + +non_null() +static void tox_event_group_topic_set_group_number(Tox_Event_Group_Topic *group_topic, + uint32_t group_number) +{ + assert(group_topic != nullptr); + group_topic->group_number = group_number; +} +uint32_t tox_event_group_topic_get_group_number(const Tox_Event_Group_Topic *group_topic) +{ + assert(group_topic != nullptr); + return group_topic->group_number; +} + +non_null() +static void tox_event_group_topic_set_peer_id(Tox_Event_Group_Topic *group_topic, + uint32_t peer_id) +{ + assert(group_topic != nullptr); + group_topic->peer_id = peer_id; +} +uint32_t tox_event_group_topic_get_peer_id(const Tox_Event_Group_Topic *group_topic) +{ + assert(group_topic != nullptr); + return group_topic->peer_id; +} + +non_null() +static bool tox_event_group_topic_set_topic(Tox_Event_Group_Topic *group_topic, + const uint8_t *topic, uint32_t topic_length) +{ + assert(group_topic != nullptr); + + if (group_topic->topic != nullptr) { + free(group_topic->topic); + group_topic->topic = nullptr; + group_topic->topic_length = 0; + } + + group_topic->topic = (uint8_t *)malloc(topic_length); + + if (group_topic->topic == nullptr) { + return false; + } + + memcpy(group_topic->topic, topic, topic_length); + group_topic->topic_length = topic_length; + return true; +} +size_t tox_event_group_topic_get_topic_length(const Tox_Event_Group_Topic *group_topic) +{ + assert(group_topic != nullptr); + return group_topic->topic_length; +} +const uint8_t *tox_event_group_topic_get_topic(const Tox_Event_Group_Topic *group_topic) +{ + assert(group_topic != nullptr); + return group_topic->topic; +} + +non_null() +static bool tox_event_group_topic_pack( + const Tox_Event_Group_Topic *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_TOPIC) + && bin_pack_array(bp, 3) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->peer_id) + && bin_pack_bin(bp, event->topic, event->topic_length); +} + +non_null() +static bool tox_event_group_topic_unpack( + Tox_Event_Group_Topic *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 3)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && bin_unpack_u32(bu, &event->peer_id) + && bin_unpack_bin(bu, &event->topic, &event->topic_length); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Topic *tox_events_add_group_topic(Tox_Events *events) +{ + if (events->group_topic_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_topic_size == events->group_topic_capacity) { + const uint32_t new_group_topic_capacity = events->group_topic_capacity * 2 + 1; + Tox_Event_Group_Topic *new_group_topic = (Tox_Event_Group_Topic *) + realloc( + events->group_topic, + new_group_topic_capacity * sizeof(Tox_Event_Group_Topic)); + + if (new_group_topic == nullptr) { + return nullptr; + } + + events->group_topic = new_group_topic; + events->group_topic_capacity = new_group_topic_capacity; + } + + Tox_Event_Group_Topic *const group_topic = + &events->group_topic[events->group_topic_size]; + tox_event_group_topic_construct(group_topic); + ++events->group_topic_size; + return group_topic; +} + +void tox_events_clear_group_topic(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_topic_size; ++i) { + tox_event_group_topic_destruct(&events->group_topic[i]); + } + + free(events->group_topic); + events->group_topic = nullptr; + events->group_topic_size = 0; + events->group_topic_capacity = 0; +} + +uint32_t tox_events_get_group_topic_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_topic_size; +} + +const Tox_Event_Group_Topic *tox_events_get_group_topic(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_topic_size); + assert(events->group_topic != nullptr); + return &events->group_topic[index]; +} + +bool tox_events_pack_group_topic(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_topic_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_topic_pack(tox_events_get_group_topic(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_topic(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Topic *event = tox_events_add_group_topic(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_topic_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_topic(Tox *tox, uint32_t group_number, uint32_t peer_id, const uint8_t *topic, size_t length, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Topic *group_topic = tox_events_add_group_topic(state->events); + + if (group_topic == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_topic_set_group_number(group_topic, group_number); + tox_event_group_topic_set_peer_id(group_topic, peer_id); + tox_event_group_topic_set_topic(group_topic, topic, length); +} diff --git a/toxcore/events/group_topic_lock.c b/toxcore/events/group_topic_lock.c new file mode 100644 index 0000000000..898fe6e35b --- /dev/null +++ b/toxcore/events/group_topic_lock.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Topic_Lock { + uint32_t group_number; + Tox_Group_Topic_Lock topic_lock; +}; + +non_null() +static void tox_event_group_topic_lock_construct(Tox_Event_Group_Topic_Lock *group_topic_lock) +{ + *group_topic_lock = (Tox_Event_Group_Topic_Lock) { + 0 + }; +} +non_null() +static void tox_event_group_topic_lock_destruct(Tox_Event_Group_Topic_Lock *group_topic_lock) +{ + return; +} + +non_null() +static void tox_event_group_topic_lock_set_group_number(Tox_Event_Group_Topic_Lock *group_topic_lock, + uint32_t group_number) +{ + assert(group_topic_lock != nullptr); + group_topic_lock->group_number = group_number; +} +uint32_t tox_event_group_topic_lock_get_group_number(const Tox_Event_Group_Topic_Lock *group_topic_lock) +{ + assert(group_topic_lock != nullptr); + return group_topic_lock->group_number; +} + +non_null() +static void tox_event_group_topic_lock_set_topic_lock(Tox_Event_Group_Topic_Lock *group_topic_lock, + Tox_Group_Topic_Lock topic_lock) +{ + assert(group_topic_lock != nullptr); + group_topic_lock->topic_lock = topic_lock; +} +Tox_Group_Topic_Lock tox_event_group_topic_lock_get_topic_lock(const Tox_Event_Group_Topic_Lock *group_topic_lock) +{ + assert(group_topic_lock != nullptr); + return group_topic_lock->topic_lock; +} + +non_null() +static bool tox_event_group_topic_lock_pack( + const Tox_Event_Group_Topic_Lock *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_TOPIC_LOCK) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->topic_lock); +} + +non_null() +static bool tox_event_group_topic_lock_unpack( + Tox_Event_Group_Topic_Lock *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && tox_unpack_group_topic_lock(bu, &event->topic_lock); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Topic_Lock *tox_events_add_group_topic_lock(Tox_Events *events) +{ + if (events->group_topic_lock_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_topic_lock_size == events->group_topic_lock_capacity) { + const uint32_t new_group_topic_lock_capacity = events->group_topic_lock_capacity * 2 + 1; + Tox_Event_Group_Topic_Lock *new_group_topic_lock = (Tox_Event_Group_Topic_Lock *) + realloc( + events->group_topic_lock, + new_group_topic_lock_capacity * sizeof(Tox_Event_Group_Topic_Lock)); + + if (new_group_topic_lock == nullptr) { + return nullptr; + } + + events->group_topic_lock = new_group_topic_lock; + events->group_topic_lock_capacity = new_group_topic_lock_capacity; + } + + Tox_Event_Group_Topic_Lock *const group_topic_lock = + &events->group_topic_lock[events->group_topic_lock_size]; + tox_event_group_topic_lock_construct(group_topic_lock); + ++events->group_topic_lock_size; + return group_topic_lock; +} + +void tox_events_clear_group_topic_lock(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_topic_lock_size; ++i) { + tox_event_group_topic_lock_destruct(&events->group_topic_lock[i]); + } + + free(events->group_topic_lock); + events->group_topic_lock = nullptr; + events->group_topic_lock_size = 0; + events->group_topic_lock_capacity = 0; +} + +uint32_t tox_events_get_group_topic_lock_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_topic_lock_size; +} + +const Tox_Event_Group_Topic_Lock *tox_events_get_group_topic_lock(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_topic_lock_size); + assert(events->group_topic_lock != nullptr); + return &events->group_topic_lock[index]; +} + +bool tox_events_pack_group_topic_lock(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_topic_lock_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_topic_lock_pack(tox_events_get_group_topic_lock(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_topic_lock(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Topic_Lock *event = tox_events_add_group_topic_lock(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_topic_lock_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_topic_lock(Tox *tox, uint32_t group_number, Tox_Group_Topic_Lock topic_lock, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Topic_Lock *group_topic_lock = tox_events_add_group_topic_lock(state->events); + + if (group_topic_lock == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_topic_lock_set_group_number(group_topic_lock, group_number); + tox_event_group_topic_lock_set_topic_lock(group_topic_lock, topic_lock); +} diff --git a/toxcore/events/group_voice_state.c b/toxcore/events/group_voice_state.c new file mode 100644 index 0000000000..8169efad75 --- /dev/null +++ b/toxcore/events/group_voice_state.c @@ -0,0 +1,214 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later + * Copyright © 2023 The TokTok team. + */ + +#include "events_alloc.h" + +#include +#include +#include + +#include "../bin_pack.h" +#include "../bin_unpack.h" +#include "../ccompat.h" +#include "../tox.h" +#include "../tox_events.h" +#include "../tox_unpack.h" + + +/***************************************************** + * + * :: struct and accessors + * + *****************************************************/ + + +struct Tox_Event_Group_Voice_State { + uint32_t group_number; + Tox_Group_Voice_State voice_state; +}; + +non_null() +static void tox_event_group_voice_state_construct(Tox_Event_Group_Voice_State *group_voice_state) +{ + *group_voice_state = (Tox_Event_Group_Voice_State) { + 0 + }; +} +non_null() +static void tox_event_group_voice_state_destruct(Tox_Event_Group_Voice_State *group_voice_state) +{ + return; +} + +non_null() +static void tox_event_group_voice_state_set_group_number(Tox_Event_Group_Voice_State *group_voice_state, + uint32_t group_number) +{ + assert(group_voice_state != nullptr); + group_voice_state->group_number = group_number; +} +uint32_t tox_event_group_voice_state_get_group_number(const Tox_Event_Group_Voice_State *group_voice_state) +{ + assert(group_voice_state != nullptr); + return group_voice_state->group_number; +} + +non_null() +static void tox_event_group_voice_state_set_voice_state(Tox_Event_Group_Voice_State *group_voice_state, + Tox_Group_Voice_State voice_state) +{ + assert(group_voice_state != nullptr); + group_voice_state->voice_state = voice_state; +} +Tox_Group_Voice_State tox_event_group_voice_state_get_voice_state(const Tox_Event_Group_Voice_State *group_voice_state) +{ + assert(group_voice_state != nullptr); + return group_voice_state->voice_state; +} + +non_null() +static bool tox_event_group_voice_state_pack( + const Tox_Event_Group_Voice_State *event, Bin_Pack *bp) +{ + assert(event != nullptr); + return bin_pack_array(bp, 2) + && bin_pack_u32(bp, TOX_EVENT_GROUP_VOICE_STATE) + && bin_pack_array(bp, 2) + && bin_pack_u32(bp, event->group_number) + && bin_pack_u32(bp, event->voice_state); +} + +non_null() +static bool tox_event_group_voice_state_unpack( + Tox_Event_Group_Voice_State *event, Bin_Unpack *bu) +{ + assert(event != nullptr); + if (!bin_unpack_array_fixed(bu, 2)) { + return false; + } + + return bin_unpack_u32(bu, &event->group_number) + && tox_unpack_group_voice_state(bu, &event->voice_state); +} + + +/***************************************************** + * + * :: add/clear/get + * + *****************************************************/ + + +non_null() +static Tox_Event_Group_Voice_State *tox_events_add_group_voice_state(Tox_Events *events) +{ + if (events->group_voice_state_size == UINT32_MAX) { + return nullptr; + } + + if (events->group_voice_state_size == events->group_voice_state_capacity) { + const uint32_t new_group_voice_state_capacity = events->group_voice_state_capacity * 2 + 1; + Tox_Event_Group_Voice_State *new_group_voice_state = (Tox_Event_Group_Voice_State *) + realloc( + events->group_voice_state, + new_group_voice_state_capacity * sizeof(Tox_Event_Group_Voice_State)); + + if (new_group_voice_state == nullptr) { + return nullptr; + } + + events->group_voice_state = new_group_voice_state; + events->group_voice_state_capacity = new_group_voice_state_capacity; + } + + Tox_Event_Group_Voice_State *const group_voice_state = + &events->group_voice_state[events->group_voice_state_size]; + tox_event_group_voice_state_construct(group_voice_state); + ++events->group_voice_state_size; + return group_voice_state; +} + +void tox_events_clear_group_voice_state(Tox_Events *events) +{ + if (events == nullptr) { + return; + } + + for (uint32_t i = 0; i < events->group_voice_state_size; ++i) { + tox_event_group_voice_state_destruct(&events->group_voice_state[i]); + } + + free(events->group_voice_state); + events->group_voice_state = nullptr; + events->group_voice_state_size = 0; + events->group_voice_state_capacity = 0; +} + +uint32_t tox_events_get_group_voice_state_size(const Tox_Events *events) +{ + if (events == nullptr) { + return 0; + } + + return events->group_voice_state_size; +} + +const Tox_Event_Group_Voice_State *tox_events_get_group_voice_state(const Tox_Events *events, uint32_t index) +{ + assert(index < events->group_voice_state_size); + assert(events->group_voice_state != nullptr); + return &events->group_voice_state[index]; +} + +bool tox_events_pack_group_voice_state(const Tox_Events *events, Bin_Pack *bp) +{ + const uint32_t size = tox_events_get_group_voice_state_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (!tox_event_group_voice_state_pack(tox_events_get_group_voice_state(events, i), bp)) { + return false; + } + } + return true; +} + +bool tox_events_unpack_group_voice_state(Tox_Events *events, Bin_Unpack *bu) +{ + Tox_Event_Group_Voice_State *event = tox_events_add_group_voice_state(events); + + if (event == nullptr) { + return false; + } + + return tox_event_group_voice_state_unpack(event, bu); +} + + +/***************************************************** + * + * :: event handler + * + *****************************************************/ + + +void tox_events_handle_group_voice_state(Tox *tox, uint32_t group_number, Tox_Group_Voice_State voice_state, + void *user_data) +{ + Tox_Events_State *state = tox_events_alloc(user_data); + assert(state != nullptr); + + if (state->events == nullptr) { + return; + } + + Tox_Event_Group_Voice_State *group_voice_state = tox_events_add_group_voice_state(state->events); + + if (group_voice_state == nullptr) { + state->error = TOX_ERR_EVENTS_ITERATE_MALLOC; + return; + } + + tox_event_group_voice_state_set_group_number(group_voice_state, group_number); + tox_event_group_voice_state_set_voice_state(group_voice_state, voice_state); +} diff --git a/toxcore/tox_dispatch.c b/toxcore/tox_dispatch.c index 5427851470..ee29437307 100644 --- a/toxcore/tox_dispatch.c +++ b/toxcore/tox_dispatch.c @@ -30,6 +30,24 @@ struct Tox_Dispatch { tox_events_friend_status_message_cb *friend_status_message_callback; tox_events_friend_typing_cb *friend_typing_callback; tox_events_self_connection_status_cb *self_connection_status_callback; + tox_events_group_peer_name_cb *group_peer_name_callback; + tox_events_group_peer_status_cb *group_peer_status_callback; + tox_events_group_topic_cb *group_topic_callback; + tox_events_group_privacy_state_cb *group_privacy_state_callback; + tox_events_group_voice_state_cb *group_voice_state_callback; + tox_events_group_topic_lock_cb *group_topic_lock_callback; + tox_events_group_peer_limit_cb *group_peer_limit_callback; + tox_events_group_password_cb *group_password_callback; + tox_events_group_message_cb *group_message_callback; + tox_events_group_private_message_cb *group_private_message_callback; + tox_events_group_custom_packet_cb *group_custom_packet_callback; + tox_events_group_custom_private_packet_cb *group_custom_private_packet_callback; + tox_events_group_invite_cb *group_invite_callback; + tox_events_group_peer_join_cb *group_peer_join_callback; + tox_events_group_peer_exit_cb *group_peer_exit_callback; + tox_events_group_self_join_cb *group_self_join_callback; + tox_events_group_join_fail_cb *group_join_fail_callback; + tox_events_group_moderation_cb *group_moderation_callback; }; Tox_Dispatch *tox_dispatch_new(Tox_Err_Dispatch_New *error) @@ -165,6 +183,96 @@ void tox_events_callback_self_connection_status( { dispatch->self_connection_status_callback = callback; } +void tox_events_callback_group_peer_name( + Tox_Dispatch *dispatch, tox_events_group_peer_name_cb *callback) +{ + dispatch->group_peer_name_callback = callback; +} +void tox_events_callback_group_peer_status( + Tox_Dispatch *dispatch, tox_events_group_peer_status_cb *callback) +{ + dispatch->group_peer_status_callback = callback; +} +void tox_events_callback_group_topic( + Tox_Dispatch *dispatch, tox_events_group_topic_cb *callback) +{ + dispatch->group_topic_callback = callback; +} +void tox_events_callback_group_privacy_state( + Tox_Dispatch *dispatch, tox_events_group_privacy_state_cb *callback) +{ + dispatch->group_privacy_state_callback = callback; +} +void tox_events_callback_group_voice_state( + Tox_Dispatch *dispatch, tox_events_group_voice_state_cb *callback) +{ + dispatch->group_voice_state_callback = callback; +} +void tox_events_callback_group_topic_lock( + Tox_Dispatch *dispatch, tox_events_group_topic_lock_cb *callback) +{ + dispatch->group_topic_lock_callback = callback; +} +void tox_events_callback_group_peer_limit( + Tox_Dispatch *dispatch, tox_events_group_peer_limit_cb *callback) +{ + dispatch->group_peer_limit_callback = callback; +} +void tox_events_callback_group_password( + Tox_Dispatch *dispatch, tox_events_group_password_cb *callback) +{ + dispatch->group_password_callback = callback; +} +void tox_events_callback_group_message( + Tox_Dispatch *dispatch, tox_events_group_message_cb *callback) +{ + dispatch->group_message_callback = callback; +} +void tox_events_callback_group_private_message( + Tox_Dispatch *dispatch, tox_events_group_private_message_cb *callback) +{ + dispatch->group_private_message_callback = callback; +} +void tox_events_callback_group_custom_packet( + Tox_Dispatch *dispatch, tox_events_group_custom_packet_cb *callback) +{ + dispatch->group_custom_packet_callback = callback; +} +void tox_events_callback_group_custom_private_packet( + Tox_Dispatch *dispatch, tox_events_group_custom_private_packet_cb *callback) +{ + dispatch->group_custom_private_packet_callback = callback; +} +void tox_events_callback_group_invite( + Tox_Dispatch *dispatch, tox_events_group_invite_cb *callback) +{ + dispatch->group_invite_callback = callback; +} +void tox_events_callback_group_peer_join( + Tox_Dispatch *dispatch, tox_events_group_peer_join_cb *callback) +{ + dispatch->group_peer_join_callback = callback; +} +void tox_events_callback_group_peer_exit( + Tox_Dispatch *dispatch, tox_events_group_peer_exit_cb *callback) +{ + dispatch->group_peer_exit_callback = callback; +} +void tox_events_callback_group_self_join( + Tox_Dispatch *dispatch, tox_events_group_self_join_cb *callback) +{ + dispatch->group_self_join_callback = callback; +} +void tox_events_callback_group_join_fail( + Tox_Dispatch *dispatch, tox_events_group_join_fail_cb *callback) +{ + dispatch->group_join_fail_callback = callback; +} +void tox_events_callback_group_moderation( + Tox_Dispatch *dispatch, tox_events_group_moderation_cb *callback) +{ + dispatch->group_moderation_callback = callback; +} non_null(1, 3) nullable(2, 4) static void tox_dispatch_invoke_conference_connected( @@ -460,6 +568,258 @@ static void tox_dispatch_invoke_self_connection_status( } } +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_peer_name( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_peer_name_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_peer_name_callback != nullptr) { + dispatch->group_peer_name_callback( + tox, tox_events_get_group_peer_name(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_peer_status( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_peer_status_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_peer_status_callback != nullptr) { + dispatch->group_peer_status_callback( + tox, tox_events_get_group_peer_status(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_topic( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_topic_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_topic_callback != nullptr) { + dispatch->group_topic_callback( + tox, tox_events_get_group_topic(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_privacy_state( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_privacy_state_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_privacy_state_callback != nullptr) { + dispatch->group_privacy_state_callback( + tox, tox_events_get_group_privacy_state(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_voice_state( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_voice_state_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_voice_state_callback != nullptr) { + dispatch->group_voice_state_callback( + tox, tox_events_get_group_voice_state(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_topic_lock( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_topic_lock_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_topic_lock_callback != nullptr) { + dispatch->group_topic_lock_callback( + tox, tox_events_get_group_topic_lock(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_peer_limit( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_peer_limit_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_peer_limit_callback != nullptr) { + dispatch->group_peer_limit_callback( + tox, tox_events_get_group_peer_limit(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_password( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_password_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_password_callback != nullptr) { + dispatch->group_password_callback( + tox, tox_events_get_group_password(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_message( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_message_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_message_callback != nullptr) { + dispatch->group_message_callback( + tox, tox_events_get_group_message(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_private_message( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_private_message_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_private_message_callback != nullptr) { + dispatch->group_private_message_callback( + tox, tox_events_get_group_private_message(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_custom_packet( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_custom_packet_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_custom_packet_callback != nullptr) { + dispatch->group_custom_packet_callback( + tox, tox_events_get_group_custom_packet(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_custom_private_packet( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_custom_private_packet_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_custom_private_packet_callback != nullptr) { + dispatch->group_custom_private_packet_callback( + tox, tox_events_get_group_custom_private_packet(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_invite( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_invite_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_invite_callback != nullptr) { + dispatch->group_invite_callback( + tox, tox_events_get_group_invite(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_peer_join( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_peer_join_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_peer_join_callback != nullptr) { + dispatch->group_peer_join_callback( + tox, tox_events_get_group_peer_join(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_peer_exit( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_peer_exit_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_peer_exit_callback != nullptr) { + dispatch->group_peer_exit_callback( + tox, tox_events_get_group_peer_exit(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_self_join( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_self_join_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_self_join_callback != nullptr) { + dispatch->group_self_join_callback( + tox, tox_events_get_group_self_join(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_join_fail( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_join_fail_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_join_fail_callback != nullptr) { + dispatch->group_join_fail_callback( + tox, tox_events_get_group_join_fail(events, i), user_data); + } + } +} + +non_null(1, 3) nullable(2, 4) +static void tox_dispatch_invoke_group_moderation( + const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) +{ + const uint32_t size = tox_events_get_group_moderation_size(events); + + for (uint32_t i = 0; i < size; ++i) { + if (dispatch->group_moderation_callback != nullptr) { + dispatch->group_moderation_callback( + tox, tox_events_get_group_moderation(events, i), user_data); + } + } +} + void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, Tox *tox, void *user_data) { tox_dispatch_invoke_conference_connected(dispatch, events, tox, user_data); @@ -483,4 +843,22 @@ void tox_dispatch_invoke(const Tox_Dispatch *dispatch, const Tox_Events *events, tox_dispatch_invoke_friend_status_message(dispatch, events, tox, user_data); tox_dispatch_invoke_friend_typing(dispatch, events, tox, user_data); tox_dispatch_invoke_self_connection_status(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_peer_name(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_peer_status(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_topic(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_privacy_state(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_voice_state(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_topic_lock(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_peer_limit(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_password(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_message(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_private_message(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_custom_packet(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_custom_private_packet(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_invite(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_peer_join(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_peer_exit(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_self_join(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_join_fail(dispatch, events, tox, user_data); + tox_dispatch_invoke_group_moderation(dispatch, events, tox, user_data); } diff --git a/toxcore/tox_dispatch.h b/toxcore/tox_dispatch.h index 7e8fbba376..bf2df13994 100644 --- a/toxcore/tox_dispatch.h +++ b/toxcore/tox_dispatch.h @@ -93,6 +93,42 @@ typedef void tox_events_friend_typing_cb( Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data); typedef void tox_events_self_connection_status_cb( Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data); +typedef void tox_events_group_peer_name_cb( + Tox *tox, const Tox_Event_Group_Peer_Name *event, void *user_data); +typedef void tox_events_group_peer_status_cb( + Tox *tox, const Tox_Event_Group_Peer_Status *event, void *user_data); +typedef void tox_events_group_topic_cb( + Tox *tox, const Tox_Event_Group_Topic *event, void *user_data); +typedef void tox_events_group_privacy_state_cb( + Tox *tox, const Tox_Event_Group_Privacy_State *event, void *user_data); +typedef void tox_events_group_voice_state_cb( + Tox *tox, const Tox_Event_Group_Voice_State *event, void *user_data); +typedef void tox_events_group_topic_lock_cb( + Tox *tox, const Tox_Event_Group_Topic_Lock *event, void *user_data); +typedef void tox_events_group_peer_limit_cb( + Tox *tox, const Tox_Event_Group_Peer_Limit *event, void *user_data); +typedef void tox_events_group_password_cb( + Tox *tox, const Tox_Event_Group_Password *event, void *user_data); +typedef void tox_events_group_message_cb( + Tox *tox, const Tox_Event_Group_Message *event, void *user_data); +typedef void tox_events_group_private_message_cb( + Tox *tox, const Tox_Event_Group_Private_Message *event, void *user_data); +typedef void tox_events_group_custom_packet_cb( + Tox *tox, const Tox_Event_Group_Custom_Packet *event, void *user_data); +typedef void tox_events_group_custom_private_packet_cb( + Tox *tox, const Tox_Event_Group_Custom_Private_Packet *event, void *user_data); +typedef void tox_events_group_invite_cb( + Tox *tox, const Tox_Event_Group_Invite *event, void *user_data); +typedef void tox_events_group_peer_join_cb( + Tox *tox, const Tox_Event_Group_Peer_Join *event, void *user_data); +typedef void tox_events_group_peer_exit_cb( + Tox *tox, const Tox_Event_Group_Peer_Exit *event, void *user_data); +typedef void tox_events_group_self_join_cb( + Tox *tox, const Tox_Event_Group_Self_Join *event, void *user_data); +typedef void tox_events_group_join_fail_cb( + Tox *tox, const Tox_Event_Group_Join_Fail *event, void *user_data); +typedef void tox_events_group_moderation_cb( + Tox *tox, const Tox_Event_Group_Moderation *event, void *user_data); void tox_events_callback_conference_connected( Tox_Dispatch *dispatch, tox_events_conference_connected_cb *callback); @@ -136,6 +172,42 @@ void tox_events_callback_friend_typing( Tox_Dispatch *dispatch, tox_events_friend_typing_cb *callback); void tox_events_callback_self_connection_status( Tox_Dispatch *dispatch, tox_events_self_connection_status_cb *callback); +void tox_events_callback_group_peer_name( + Tox_Dispatch *dispatch, tox_events_group_peer_name_cb *callback); +void tox_events_callback_group_peer_status( + Tox_Dispatch *dispatch, tox_events_group_peer_status_cb *callback); +void tox_events_callback_group_topic( + Tox_Dispatch *dispatch, tox_events_group_topic_cb *callback); +void tox_events_callback_group_privacy_state( + Tox_Dispatch *dispatch, tox_events_group_privacy_state_cb *callback); +void tox_events_callback_group_voice_state( + Tox_Dispatch *dispatch, tox_events_group_voice_state_cb *callback); +void tox_events_callback_group_topic_lock( + Tox_Dispatch *dispatch, tox_events_group_topic_lock_cb *callback); +void tox_events_callback_group_peer_limit( + Tox_Dispatch *dispatch, tox_events_group_peer_limit_cb *callback); +void tox_events_callback_group_password( + Tox_Dispatch *dispatch, tox_events_group_password_cb *callback); +void tox_events_callback_group_message( + Tox_Dispatch *dispatch, tox_events_group_message_cb *callback); +void tox_events_callback_group_private_message( + Tox_Dispatch *dispatch, tox_events_group_private_message_cb *callback); +void tox_events_callback_group_custom_packet( + Tox_Dispatch *dispatch, tox_events_group_custom_packet_cb *callback); +void tox_events_callback_group_custom_private_packet( + Tox_Dispatch *dispatch, tox_events_group_custom_private_packet_cb *callback); +void tox_events_callback_group_invite( + Tox_Dispatch *dispatch, tox_events_group_invite_cb *callback); +void tox_events_callback_group_peer_join( + Tox_Dispatch *dispatch, tox_events_group_peer_join_cb *callback); +void tox_events_callback_group_peer_exit( + Tox_Dispatch *dispatch, tox_events_group_peer_exit_cb *callback); +void tox_events_callback_group_self_join( + Tox_Dispatch *dispatch, tox_events_group_self_join_cb *callback); +void tox_events_callback_group_join_fail( + Tox_Dispatch *dispatch, tox_events_group_join_fail_cb *callback); +void tox_events_callback_group_moderation( + Tox_Dispatch *dispatch, tox_events_group_moderation_cb *callback); #ifdef __cplusplus } diff --git a/toxcore/tox_events.c b/toxcore/tox_events.c index 91a7767f7b..528649f912 100644 --- a/toxcore/tox_events.c +++ b/toxcore/tox_events.c @@ -44,6 +44,24 @@ void tox_events_init(Tox *tox) tox_callback_friend_status(tox, tox_events_handle_friend_status); tox_callback_friend_typing(tox, tox_events_handle_friend_typing); tox_callback_self_connection_status(tox, tox_events_handle_self_connection_status); + tox_callback_group_peer_name(tox, tox_events_handle_group_peer_name); + tox_callback_group_peer_status(tox, tox_events_handle_group_peer_status); + tox_callback_group_topic(tox, tox_events_handle_group_topic); + tox_callback_group_privacy_state(tox, tox_events_handle_group_privacy_state); + tox_callback_group_voice_state(tox, tox_events_handle_group_voice_state); + tox_callback_group_topic_lock(tox, tox_events_handle_group_topic_lock); + tox_callback_group_peer_limit(tox, tox_events_handle_group_peer_limit); + tox_callback_group_password(tox, tox_events_handle_group_password); + tox_callback_group_message(tox, tox_events_handle_group_message); + tox_callback_group_private_message(tox, tox_events_handle_group_private_message); + tox_callback_group_custom_packet(tox, tox_events_handle_group_custom_packet); + tox_callback_group_custom_private_packet(tox, tox_events_handle_group_custom_private_packet); + tox_callback_group_invite(tox, tox_events_handle_group_invite); + tox_callback_group_peer_join(tox, tox_events_handle_group_peer_join); + tox_callback_group_peer_exit(tox, tox_events_handle_group_peer_exit); + tox_callback_group_self_join(tox, tox_events_handle_group_self_join); + tox_callback_group_join_fail(tox, tox_events_handle_group_join_fail); + tox_callback_group_moderation(tox, tox_events_handle_group_moderation); } Tox_Events *tox_events_iterate(Tox *tox, bool fail_hard, Tox_Err_Events_Iterate *error) @@ -85,7 +103,25 @@ bool tox_events_pack(const Tox_Events *events, Bin_Pack *bp) + tox_events_get_friend_status_message_size(events) + tox_events_get_friend_status_size(events) + tox_events_get_friend_typing_size(events) - + tox_events_get_self_connection_status_size(events); + + tox_events_get_self_connection_status_size(events) + + tox_events_get_group_peer_name_size(events) + + tox_events_get_group_peer_status_size(events) + + tox_events_get_group_topic_size(events) + + tox_events_get_group_privacy_state_size(events) + + tox_events_get_group_voice_state_size(events) + + tox_events_get_group_topic_lock_size(events) + + tox_events_get_group_peer_limit_size(events) + + tox_events_get_group_password_size(events) + + tox_events_get_group_message_size(events) + + tox_events_get_group_private_message_size(events) + + tox_events_get_group_custom_packet_size(events) + + tox_events_get_group_custom_private_packet_size(events) + + tox_events_get_group_invite_size(events) + + tox_events_get_group_peer_join_size(events) + + tox_events_get_group_peer_exit_size(events) + + tox_events_get_group_self_join_size(events) + + tox_events_get_group_join_fail_size(events) + + tox_events_get_group_moderation_size(events); return bin_pack_array(bp, count) && tox_events_pack_conference_connected(events, bp) @@ -108,7 +144,25 @@ bool tox_events_pack(const Tox_Events *events, Bin_Pack *bp) && tox_events_pack_friend_status_message(events, bp) && tox_events_pack_friend_status(events, bp) && tox_events_pack_friend_typing(events, bp) - && tox_events_pack_self_connection_status(events, bp); + && tox_events_pack_self_connection_status(events, bp) + && tox_events_pack_group_peer_name(events, bp) + && tox_events_pack_group_peer_status(events, bp) + && tox_events_pack_group_topic(events, bp) + && tox_events_pack_group_privacy_state(events, bp) + && tox_events_pack_group_voice_state(events, bp) + && tox_events_pack_group_topic_lock(events, bp) + && tox_events_pack_group_peer_limit(events, bp) + && tox_events_pack_group_password(events, bp) + && tox_events_pack_group_message(events, bp) + && tox_events_pack_group_private_message(events, bp) + && tox_events_pack_group_custom_packet(events, bp) + && tox_events_pack_group_custom_private_packet(events, bp) + && tox_events_pack_group_invite(events, bp) + && tox_events_pack_group_peer_join(events, bp) + && tox_events_pack_group_peer_exit(events, bp) + && tox_events_pack_group_self_join(events, bp) + && tox_events_pack_group_join_fail(events, bp) + && tox_events_pack_group_moderation(events, bp); } non_null() @@ -192,6 +246,60 @@ static bool tox_event_unpack(Tox_Events *events, Bin_Unpack *bu) case TOX_EVENT_SELF_CONNECTION_STATUS: return tox_events_unpack_self_connection_status(events, bu); + case TOX_EVENT_GROUP_PEER_NAME: + return tox_events_unpack_group_peer_name(events, bu); + + case TOX_EVENT_GROUP_PEER_STATUS: + return tox_events_unpack_group_peer_status(events, bu); + + case TOX_EVENT_GROUP_TOPIC: + return tox_events_unpack_group_topic(events, bu); + + case TOX_EVENT_GROUP_PRIVACY_STATE: + return tox_events_unpack_group_privacy_state(events, bu); + + case TOX_EVENT_GROUP_VOICE_STATE: + return tox_events_unpack_group_voice_state(events, bu); + + case TOX_EVENT_GROUP_TOPIC_LOCK: + return tox_events_unpack_group_topic_lock(events, bu); + + case TOX_EVENT_GROUP_PEER_LIMIT: + return tox_events_unpack_group_peer_limit(events, bu); + + case TOX_EVENT_GROUP_PASSWORD: + return tox_events_unpack_group_password(events, bu); + + case TOX_EVENT_GROUP_MESSAGE: + return tox_events_unpack_group_message(events, bu); + + case TOX_EVENT_GROUP_PRIVATE_MESSAGE: + return tox_events_unpack_group_private_message(events, bu); + + case TOX_EVENT_GROUP_CUSTOM_PACKET: + return tox_events_unpack_group_custom_packet(events, bu); + + case TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET: + return tox_events_unpack_group_custom_private_packet(events, bu); + + case TOX_EVENT_GROUP_INVITE: + return tox_events_unpack_group_invite(events, bu); + + case TOX_EVENT_GROUP_PEER_JOIN: + return tox_events_unpack_group_peer_join(events, bu); + + case TOX_EVENT_GROUP_PEER_EXIT: + return tox_events_unpack_group_peer_exit(events, bu); + + case TOX_EVENT_GROUP_SELF_JOIN: + return tox_events_unpack_group_self_join(events, bu); + + case TOX_EVENT_GROUP_JOIN_FAIL: + return tox_events_unpack_group_join_fail(events, bu); + + case TOX_EVENT_GROUP_MODERATION: + return tox_events_unpack_group_moderation(events, bu); + default: return false; } diff --git a/toxcore/tox_events.h b/toxcore/tox_events.h index f33a71b29c..e09ccaa208 100644 --- a/toxcore/tox_events.h +++ b/toxcore/tox_events.h @@ -183,6 +183,165 @@ typedef struct Tox_Event_Self_Connection_Status Tox_Event_Self_Connection_Status Tox_Connection tox_event_self_connection_status_get_connection_status( const Tox_Event_Self_Connection_Status *self_connection_status); +typedef struct Tox_Event_Group_Peer_Name Tox_Event_Group_Peer_Name; +uint32_t tox_event_group_peer_name_get_group_number( + const Tox_Event_Group_Peer_Name *group_peer_name); +uint32_t tox_event_group_peer_name_get_peer_id( + const Tox_Event_Group_Peer_Name *group_peer_name); +const uint8_t *tox_event_group_peer_name_get_name( + const Tox_Event_Group_Peer_Name *group_peer_name); +size_t tox_event_group_peer_name_get_name_length( + const Tox_Event_Group_Peer_Name *group_peer_name); + +typedef struct Tox_Event_Group_Peer_Status Tox_Event_Group_Peer_Status; +uint32_t tox_event_group_peer_status_get_group_number( + const Tox_Event_Group_Peer_Status *group_peer_status); +uint32_t tox_event_group_peer_status_get_peer_id( + const Tox_Event_Group_Peer_Status *group_peer_status); +Tox_User_Status tox_event_group_peer_status_get_status( + const Tox_Event_Group_Peer_Status *group_peer_status); + +typedef struct Tox_Event_Group_Topic Tox_Event_Group_Topic; +uint32_t tox_event_group_topic_get_group_number( + const Tox_Event_Group_Topic *group_topic); +uint32_t tox_event_group_topic_get_peer_id( + const Tox_Event_Group_Topic *group_topic); +const uint8_t *tox_event_group_topic_get_topic( + const Tox_Event_Group_Topic *group_topic); +size_t tox_event_group_topic_get_topic_length( + const Tox_Event_Group_Topic *group_topic); + +typedef struct Tox_Event_Group_Privacy_State Tox_Event_Group_Privacy_State; +uint32_t tox_event_group_privacy_state_get_group_number( + const Tox_Event_Group_Privacy_State *group_privacy_state); +Tox_Group_Privacy_State tox_event_group_privacy_state_get_privacy_state( + const Tox_Event_Group_Privacy_State *group_privacy_state); + +typedef struct Tox_Event_Group_Voice_State Tox_Event_Group_Voice_State; +uint32_t tox_event_group_voice_state_get_group_number( + const Tox_Event_Group_Voice_State *group_voice_state); +Tox_Group_Voice_State tox_event_group_voice_state_get_voice_state( + const Tox_Event_Group_Voice_State *group_voice_state); + +typedef struct Tox_Event_Group_Topic_Lock Tox_Event_Group_Topic_Lock; +uint32_t tox_event_group_topic_lock_get_group_number( + const Tox_Event_Group_Topic_Lock *group_topic_lock); +Tox_Group_Topic_Lock tox_event_group_topic_lock_get_topic_lock( + const Tox_Event_Group_Topic_Lock *group_topic_lock); + +typedef struct Tox_Event_Group_Peer_Limit Tox_Event_Group_Peer_Limit; +uint32_t tox_event_group_peer_limit_get_group_number( + const Tox_Event_Group_Peer_Limit *group_peer_limit); +uint32_t tox_event_group_peer_limit_get_peer_limit( + const Tox_Event_Group_Peer_Limit *group_peer_limit); + +typedef struct Tox_Event_Group_Password Tox_Event_Group_Password; +uint32_t tox_event_group_password_get_group_number( + const Tox_Event_Group_Password *group_password); +const uint8_t *tox_event_group_password_get_password( + const Tox_Event_Group_Password *group_password); +size_t tox_event_group_password_get_password_length( + const Tox_Event_Group_Password *group_password); + +typedef struct Tox_Event_Group_Message Tox_Event_Group_Message; +uint32_t tox_event_group_message_get_group_number( + const Tox_Event_Group_Message *group_message); +uint32_t tox_event_group_message_get_peer_id( + const Tox_Event_Group_Message *group_message); +Tox_Message_Type tox_event_group_message_get_type( + const Tox_Event_Group_Message *group_message); +const uint8_t *tox_event_group_message_get_message( + const Tox_Event_Group_Message *group_message); +size_t tox_event_group_message_get_message_length( + const Tox_Event_Group_Message *group_message); +uint32_t tox_event_group_message_get_message_id( + const Tox_Event_Group_Message *group_message); + +typedef struct Tox_Event_Group_Private_Message Tox_Event_Group_Private_Message; +uint32_t tox_event_group_private_message_get_group_number( + const Tox_Event_Group_Private_Message *group_private_message); +uint32_t tox_event_group_private_message_get_peer_id( + const Tox_Event_Group_Private_Message *group_private_message); +Tox_Message_Type tox_event_group_private_message_get_type( + const Tox_Event_Group_Private_Message *group_private_message); +const uint8_t *tox_event_group_private_message_get_message( + const Tox_Event_Group_Private_Message *group_private_message); +size_t tox_event_group_private_message_get_message_length( + const Tox_Event_Group_Private_Message *group_private_message); + +typedef struct Tox_Event_Group_Custom_Packet Tox_Event_Group_Custom_Packet; +uint32_t tox_event_group_custom_packet_get_group_number( + const Tox_Event_Group_Custom_Packet *group_custom_packet); +uint32_t tox_event_group_custom_packet_get_peer_id( + const Tox_Event_Group_Custom_Packet *group_custom_packet); +const uint8_t *tox_event_group_custom_packet_get_data( + const Tox_Event_Group_Custom_Packet *group_custom_packet); +size_t tox_event_group_custom_packet_get_data_length( + const Tox_Event_Group_Custom_Packet *group_custom_packet); + +typedef struct Tox_Event_Group_Custom_Private_Packet Tox_Event_Group_Custom_Private_Packet; +uint32_t tox_event_group_custom_private_packet_get_group_number( + const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet); +uint32_t tox_event_group_custom_private_packet_get_peer_id( + const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet); +const uint8_t *tox_event_group_custom_private_packet_get_data( + const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet); +size_t tox_event_group_custom_private_packet_get_data_length( + const Tox_Event_Group_Custom_Private_Packet *group_custom_private_packet); + +typedef struct Tox_Event_Group_Invite Tox_Event_Group_Invite; +uint32_t tox_event_group_invite_get_friend_number( + const Tox_Event_Group_Invite *group_invite); +const uint8_t *tox_event_group_invite_get_invite_data( + const Tox_Event_Group_Invite *group_invite); +size_t tox_event_group_invite_get_invite_data_length( + const Tox_Event_Group_Invite *group_invite); +const uint8_t *tox_event_group_invite_get_group_name( + const Tox_Event_Group_Invite *group_invite); +size_t tox_event_group_invite_get_group_name_length( + const Tox_Event_Group_Invite *group_invite); + +typedef struct Tox_Event_Group_Peer_Join Tox_Event_Group_Peer_Join; +uint32_t tox_event_group_peer_join_get_group_number( + const Tox_Event_Group_Peer_Join *group_peer_join); +uint32_t tox_event_group_peer_join_get_peer_id( + const Tox_Event_Group_Peer_Join *group_peer_join); + +typedef struct Tox_Event_Group_Peer_Exit Tox_Event_Group_Peer_Exit; +uint32_t tox_event_group_peer_exit_get_group_number( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +uint32_t tox_event_group_peer_exit_get_peer_id( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +Tox_Group_Exit_Type tox_event_group_peer_exit_get_exit_type( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +const uint8_t *tox_event_group_peer_exit_get_name( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +size_t tox_event_group_peer_exit_get_name_length( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +const uint8_t *tox_event_group_peer_exit_get_part_message( + const Tox_Event_Group_Peer_Exit *group_peer_exit); +size_t tox_event_group_peer_exit_get_part_message_length( + const Tox_Event_Group_Peer_Exit *group_peer_exit); + +typedef struct Tox_Event_Group_Self_Join Tox_Event_Group_Self_Join; +uint32_t tox_event_group_self_join_get_group_number( + const Tox_Event_Group_Self_Join *group_self_join); + +typedef struct Tox_Event_Group_Join_Fail Tox_Event_Group_Join_Fail; +uint32_t tox_event_group_join_fail_get_group_number( + const Tox_Event_Group_Join_Fail *group_join_fail); +Tox_Group_Join_Fail tox_event_group_join_fail_get_fail_type( + const Tox_Event_Group_Join_Fail *group_join_fail); + +typedef struct Tox_Event_Group_Moderation Tox_Event_Group_Moderation; +uint32_t tox_event_group_moderation_get_group_number( + const Tox_Event_Group_Moderation *group_moderation); +uint32_t tox_event_group_moderation_get_source_peer_id( + const Tox_Event_Group_Moderation *group_moderation); +uint32_t tox_event_group_moderation_get_target_peer_id( + const Tox_Event_Group_Moderation *group_moderation); +Tox_Group_Mod_Event tox_event_group_moderation_get_mod_type( + const Tox_Event_Group_Moderation *group_moderation); typedef enum Tox_Event { TOX_EVENT_SELF_CONNECTION_STATUS = 0, @@ -212,6 +371,25 @@ typedef enum Tox_Event { TOX_EVENT_CONFERENCE_TITLE = 19, TOX_EVENT_CONFERENCE_MESSAGE = 20, + + TOX_EVENT_GROUP_PEER_NAME = 21, + TOX_EVENT_GROUP_PEER_STATUS = 22, + TOX_EVENT_GROUP_TOPIC = 23, + TOX_EVENT_GROUP_PRIVACY_STATE = 24, + TOX_EVENT_GROUP_VOICE_STATE = 25, + TOX_EVENT_GROUP_TOPIC_LOCK = 26, + TOX_EVENT_GROUP_PEER_LIMIT = 27, + TOX_EVENT_GROUP_PASSWORD = 28, + TOX_EVENT_GROUP_MESSAGE = 29, + TOX_EVENT_GROUP_PRIVATE_MESSAGE = 30, + TOX_EVENT_GROUP_CUSTOM_PACKET = 31, + TOX_EVENT_GROUP_CUSTOM_PRIVATE_PACKET = 32, + TOX_EVENT_GROUP_INVITE = 33, + TOX_EVENT_GROUP_PEER_JOIN = 34, + TOX_EVENT_GROUP_PEER_EXIT = 35, + TOX_EVENT_GROUP_SELF_JOIN = 36, + TOX_EVENT_GROUP_JOIN_FAIL = 37, + TOX_EVENT_GROUP_MODERATION = 38, } Tox_Event; /** @@ -242,6 +420,24 @@ uint32_t tox_events_get_friend_status_message_size(const Tox_Events *events); uint32_t tox_events_get_friend_status_size(const Tox_Events *events); uint32_t tox_events_get_friend_typing_size(const Tox_Events *events); uint32_t tox_events_get_self_connection_status_size(const Tox_Events *events); +uint32_t tox_events_get_group_peer_name_size(const Tox_Events *events); +uint32_t tox_events_get_group_peer_status_size(const Tox_Events *events); +uint32_t tox_events_get_group_topic_size(const Tox_Events *events); +uint32_t tox_events_get_group_privacy_state_size(const Tox_Events *events); +uint32_t tox_events_get_group_voice_state_size(const Tox_Events *events); +uint32_t tox_events_get_group_topic_lock_size(const Tox_Events *events); +uint32_t tox_events_get_group_peer_limit_size(const Tox_Events *events); +uint32_t tox_events_get_group_password_size(const Tox_Events *events); +uint32_t tox_events_get_group_message_size(const Tox_Events *events); +uint32_t tox_events_get_group_private_message_size(const Tox_Events *events); +uint32_t tox_events_get_group_custom_packet_size(const Tox_Events *events); +uint32_t tox_events_get_group_custom_private_packet_size(const Tox_Events *events); +uint32_t tox_events_get_group_invite_size(const Tox_Events *events); +uint32_t tox_events_get_group_peer_join_size(const Tox_Events *events); +uint32_t tox_events_get_group_peer_exit_size(const Tox_Events *events); +uint32_t tox_events_get_group_self_join_size(const Tox_Events *events); +uint32_t tox_events_get_group_join_fail_size(const Tox_Events *events); +uint32_t tox_events_get_group_moderation_size(const Tox_Events *events); const Tox_Event_Conference_Connected *tox_events_get_conference_connected( const Tox_Events *events, uint32_t index); @@ -285,6 +481,42 @@ const Tox_Event_Friend_Typing *tox_events_get_friend_typing( const Tox_Events *events, uint32_t index); const Tox_Event_Self_Connection_Status *tox_events_get_self_connection_status( const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Peer_Name *tox_events_get_group_peer_name( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Peer_Status *tox_events_get_group_peer_status( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Topic *tox_events_get_group_topic( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Privacy_State *tox_events_get_group_privacy_state( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Voice_State *tox_events_get_group_voice_state( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Topic_Lock *tox_events_get_group_topic_lock( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Peer_Limit *tox_events_get_group_peer_limit( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Password *tox_events_get_group_password( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Message *tox_events_get_group_message( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Private_Message *tox_events_get_group_private_message( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Custom_Packet *tox_events_get_group_custom_packet( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Custom_Private_Packet *tox_events_get_group_custom_private_packet( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Invite *tox_events_get_group_invite( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Peer_Join *tox_events_get_group_peer_join( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Peer_Exit *tox_events_get_group_peer_exit( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Self_Join *tox_events_get_group_self_join( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Join_Fail *tox_events_get_group_join_fail( + const Tox_Events *events, uint32_t index); +const Tox_Event_Group_Moderation *tox_events_get_group_moderation( + const Tox_Events *events, uint32_t index); /** * Initialise the events recording system. diff --git a/toxcore/tox_unpack.c b/toxcore/tox_unpack.c index 6508399e7e..26d1c767f0 100644 --- a/toxcore/tox_unpack.c +++ b/toxcore/tox_unpack.c @@ -68,3 +68,75 @@ bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val) *val = (Tox_User_Status)u32; return true; } + +bool tox_unpack_group_privacy_state(Bin_Unpack *bu, Tox_Group_Privacy_State *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Privacy_State)u32; + return true; +} + +bool tox_unpack_group_voice_state(Bin_Unpack *bu, Tox_Group_Voice_State *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Voice_State)u32; + return true; +} + +bool tox_unpack_group_topic_lock(Bin_Unpack *bu, Tox_Group_Topic_Lock *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Topic_Lock)u32; + return true; +} + +bool tox_unpack_group_join_fail(Bin_Unpack *bu, Tox_Group_Join_Fail *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Join_Fail)u32; + return true; +} + +bool tox_unpack_group_mod_event(Bin_Unpack *bu, Tox_Group_Mod_Event *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Mod_Event)u32; + return true; +} + +bool tox_unpack_group_exit_type(Bin_Unpack *bu, Tox_Group_Exit_Type *val) +{ + uint32_t u32; + + if (!bin_unpack_u32(bu, &u32)) { + return false; + } + + *val = (Tox_Group_Exit_Type)u32; + return true; +} diff --git a/toxcore/tox_unpack.h b/toxcore/tox_unpack.h index 5f0b18ad1b..69bb207b5a 100644 --- a/toxcore/tox_unpack.h +++ b/toxcore/tox_unpack.h @@ -14,5 +14,11 @@ non_null() bool tox_unpack_connection(Bin_Unpack *bu, Tox_Connection *val); non_null() bool tox_unpack_file_control(Bin_Unpack *bu, Tox_File_Control *val); non_null() bool tox_unpack_message_type(Bin_Unpack *bu, Tox_Message_Type *val); non_null() bool tox_unpack_user_status(Bin_Unpack *bu, Tox_User_Status *val); +non_null() bool tox_unpack_group_privacy_state(Bin_Unpack *bu, Tox_Group_Privacy_State *val); +non_null() bool tox_unpack_group_voice_state(Bin_Unpack *bu, Tox_Group_Voice_State *val); +non_null() bool tox_unpack_group_topic_lock(Bin_Unpack *bu, Tox_Group_Topic_Lock *val); +non_null() bool tox_unpack_group_join_fail(Bin_Unpack *bu, Tox_Group_Join_Fail *val); +non_null() bool tox_unpack_group_mod_event(Bin_Unpack *bu, Tox_Group_Mod_Event *val); +non_null() bool tox_unpack_group_exit_type(Bin_Unpack *bu, Tox_Group_Exit_Type *val); #endif // C_TOXCORE_TOXCORE_TOX_UNPACK_H