diff --git a/include/matrix/roomcxn.hpp b/include/matrix/roomcxn.hpp index 8382680..4b9cb1d 100644 --- a/include/matrix/roomcxn.hpp +++ b/include/matrix/roomcxn.hpp @@ -25,6 +25,8 @@ #include "raii/rjp_string.hpp" #include "matrix/room_url_list.hpp" +#include + namespace matrix{ class roomcxn : public connection @@ -44,15 +46,16 @@ namespace matrix{ roomcxn& operator=(const roomcxn&) = default; roomcxn& operator=(roomcxn&&) = default; + //membership bool join_room(void)const; bool leave_room(void)const; - [[deprecated("Use client::join_room instead")]] bool accept_invite(void)const; [[deprecated("Use client::leave_room instead")]] bool reject_invite(void)const; + std::vector members(void)const; - + //sending events raii::rjp_string send_custom_event(const raii::string_base& event, const raii::string_base& eventtype)const; raii::rjp_string send_message(const raii::string_base& text)const; raii::rjp_string send_file(const file_info& file)const; @@ -65,6 +68,8 @@ namespace matrix{ raii::rjp_string redact_event(const raii::string_base& eventid, const raii::string_base& reason)const; raii::rjp_string redact_event(const raii::string_base& eventid)const; + + //meta stuff void regenerate_urls(void); private: diff --git a/src/matrix/roomcxn.cpp b/src/matrix/roomcxn.cpp index a2ff454..94e5100 100644 --- a/src/matrix/roomcxn.cpp +++ b/src/matrix/roomcxn.cpp @@ -23,6 +23,7 @@ #include "raii/rjp_ptr.hpp" #include //move +#include namespace matrix{ @@ -46,6 +47,75 @@ namespace matrix{ return leave_room(); } + enum class membership_event_type{ + leave, + join, + invite, + inval + }; + static membership_event_type str_to_membership_event(const char* str){ + if(!strcmp(str, "leave")) + return membership_event_type::leave; + else if(!strcmp(str, "join")) + return membership_event_type::join; + else if(!strcmp(str, "invite")) + return membership_event_type::invite; + else + return membership_event_type::inval; + } + std::vector roomcxn::members(void)const{ + struct user_info{ + RJP_int age; + membership_event_type op; + }; + struct string_comp{ + bool operator()(const raii::rjp_string& a, const raii::rjp_string& b)const{ + return strcmp(a, b); + } + }; + std::vector retval; + std::map users; + + raii::string resp = _get_curl(m_urls.room_members()); + if(!resp) return {}; + raii::rjp_ptr root(rjp_parse(resp.get())); + if(!root) return {}; + RJP_search_res res = rjp_search_member(root.get(), "chunk", 0); + if(!res.value) return{}; + + for(RJP_value* elem = rjp_get_element(res.value);elem;elem = rjp_next_element(elem)){ + raii::rjp_string userid; + RJP_int age = 0; + membership_event_type op = membership_event_type::inval; + for(RJP_value* mem = rjp_get_member(elem);mem;mem = rjp_next_member(mem)){ + if(!strcmp(rjp_member_name(mem), "state_key")){ + userid = mem; + }else if(!strcmp(rjp_member_name(mem), "age")){ + age = rjp_value_integer(mem); + }else if(!strcmp(rjp_member_name(mem), "content")){ + res = rjp_search_member(mem, "membership", 0); + if(!res.value) continue; + op = str_to_membership_event(rjp_value_string(res.value)); + } + if(age && userid && op != membership_event_type::inval){ + auto entry = users.find(userid); + if(entry != users.end() && entry->second.age > age){ + entry->second.age = age; + entry->second.op = op; + }else if(entry == users.end()){ + users.emplace(std::make_pair(raii::string(userid), user_info{age, op})); + } + break; + } + } + } + for(auto it = users.begin();it != users.end();++it){ + if(it->second.op == membership_event_type::join) + retval.push_back(std::move(it->first)); + } + return retval; + } + raii::rjp_string roomcxn::send_custom_event(const raii::string_base& event, const raii::string_base& eventtype)const{ return _post_and_find( event,