Changed syncing to return a sync::response object to make for easier parsing with a to-be-standard api
This commit is contained in:
parent
6feadbcdf8
commit
577af3c040
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ data
|
|||||||
testout
|
testout
|
||||||
audio
|
audio
|
||||||
video
|
video
|
||||||
|
result*.json
|
||||||
|
dissection_result*.txt
|
||||||
|
|||||||
4
doc/TODO
4
doc/TODO
@ -22,7 +22,11 @@ matrix:
|
|||||||
1:query/addto public room directory
|
1:query/addto public room directory
|
||||||
1:deactivate account
|
1:deactivate account
|
||||||
1:user search
|
1:user search
|
||||||
|
sync:
|
||||||
|
3:filters
|
||||||
room:
|
room:
|
||||||
|
10:query previous messages
|
||||||
|
3:message query filters
|
||||||
2:kick users
|
2:kick users
|
||||||
2:ban/unban users
|
2:ban/unban users
|
||||||
2:forget room
|
2:forget room
|
||||||
|
|||||||
113
include/matrix/events.hpp
Normal file
113
include/matrix/events.hpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of r0nk, atlas_moon, and rexy's matrix client
|
||||||
|
Copyright (C) 2019 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MATRIX_EVENT_HPP
|
||||||
|
#define MATRIX_EVENT_HPP
|
||||||
|
|
||||||
|
#include "raii/rjp_ptr.hpp"
|
||||||
|
#include "raii/static_string.hpp"
|
||||||
|
#include "raii/rjp_string.hpp"
|
||||||
|
|
||||||
|
namespace matrix::sync{
|
||||||
|
|
||||||
|
/*
|
||||||
|
Base class for events returned by a sync
|
||||||
|
*/
|
||||||
|
class event
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
RJP_value* m_event;
|
||||||
|
public:
|
||||||
|
constexpr explicit event(RJP_value* ev):
|
||||||
|
m_event(ev){}
|
||||||
|
constexpr event(const event&) = default;
|
||||||
|
~event(void) = default;
|
||||||
|
constexpr event& operator=(const event&) = default;
|
||||||
|
|
||||||
|
raii::static_string type(void)const&;
|
||||||
|
raii::rjp_string type(void)&&;
|
||||||
|
const RJP_value* content(void)const;
|
||||||
|
RJP_value* content(void);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Base class for events associated with a room returned by a sync
|
||||||
|
*/
|
||||||
|
class room_event_base
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
const raii::static_string m_roomid;
|
||||||
|
public:
|
||||||
|
constexpr room_event_base(const raii::string_base& roomid):
|
||||||
|
m_roomid(roomid.get(), roomid.length()){}
|
||||||
|
constexpr const raii::static_string& roomid(void)const{
|
||||||
|
return m_roomid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to represent a single event associated with a specific room.
|
||||||
|
*/
|
||||||
|
class room_event : public room_event_base, public event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr room_event(RJP_value* ev, const raii::string_base& roomid):
|
||||||
|
room_event_base(roomid), event(ev){}
|
||||||
|
|
||||||
|
raii::static_string eventid(void)const&;
|
||||||
|
raii::rjp_string eventid(void)&&;
|
||||||
|
raii::static_string sender(void)const&;
|
||||||
|
raii::rjp_string sender(void)&&;
|
||||||
|
int origin_server_ts(void)const;
|
||||||
|
const RJP_value* extra(void)const;
|
||||||
|
RJP_value* extra(void);
|
||||||
|
|
||||||
|
//only for m.room.redacts events
|
||||||
|
raii::static_string redacts(void)const&;
|
||||||
|
raii::rjp_string redacts(void)&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to represent a single state event associated with a specific room
|
||||||
|
*/
|
||||||
|
class room_state_event : public room_event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr room_state_event(RJP_value* ev, const raii::string_base& roomid):
|
||||||
|
room_event(ev, roomid){}
|
||||||
|
|
||||||
|
raii::static_string state_key(void)const&;
|
||||||
|
raii::rjp_string state_key(void)&&;
|
||||||
|
raii::static_string prev_content(void)const&;
|
||||||
|
raii::rjp_string prev_content(void)&&;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class to represent a single ephemeral event associated with a specific room
|
||||||
|
*/
|
||||||
|
class room_ephemeral_event : public room_event_base, public event
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
constexpr room_ephemeral_event(RJP_value* ev, const raii::string_base& roomid):
|
||||||
|
room_event_base(roomid),event(ev){}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
166
include/matrix/iterable.hpp
Normal file
166
include/matrix/iterable.hpp
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of r0nk, atlas_moon, and rexy's matrix client
|
||||||
|
Copyright (C) 2019 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MATRIX_ITERABLE_HPP
|
||||||
|
#define MATRIX_ITERABLE_HPP
|
||||||
|
|
||||||
|
#include "matrix/events.hpp"
|
||||||
|
#include "raii/rjp_string.hpp"
|
||||||
|
#include "raii/static_string.hpp"
|
||||||
|
#include "raii/rjp_iterator.hpp"
|
||||||
|
|
||||||
|
namespace matrix::sync{
|
||||||
|
|
||||||
|
namespace detail{
|
||||||
|
/*
|
||||||
|
Class for iterating over an event array returned by a sync
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class event_iterator
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
raii::rjp_array_iterator m_event;
|
||||||
|
public:
|
||||||
|
constexpr event_iterator(RJP_value* v):
|
||||||
|
m_event(v){}
|
||||||
|
constexpr event_iterator(const event_iterator& i):
|
||||||
|
m_event(i.m_event){}
|
||||||
|
constexpr bool operator==(const event_iterator& e){
|
||||||
|
return m_event == e.m_event;
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const event_iterator& e){
|
||||||
|
return m_event != e.m_event;
|
||||||
|
}
|
||||||
|
event_iterator& operator++(void){
|
||||||
|
++m_event;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr T operator*(void){
|
||||||
|
return T(*m_event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
Class for iterating over an event array associated with a room returned by a sync
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class room_event_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
raii::rjp_array_iterator m_event;
|
||||||
|
raii::static_string m_roomid;
|
||||||
|
public:
|
||||||
|
constexpr room_event_iterator(RJP_value* v, const raii::string_base& roomid):
|
||||||
|
m_event(v), m_roomid(roomid){}
|
||||||
|
constexpr room_event_iterator(const room_event_iterator& i):
|
||||||
|
m_event(i.m_event), m_roomid(i.m_roomid){}
|
||||||
|
constexpr bool operator==(const room_event_iterator& e){
|
||||||
|
return m_event == e.m_event;
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const room_event_iterator& e){
|
||||||
|
return m_event != e.m_event;
|
||||||
|
}
|
||||||
|
room_event_iterator& operator++(void){
|
||||||
|
++m_event;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr T operator*(void){
|
||||||
|
return T(*m_event, m_roomid);
|
||||||
|
}
|
||||||
|
constexpr const raii::static_string& roomid(void)const{
|
||||||
|
return m_roomid;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Base class shared by all room lists
|
||||||
|
*/
|
||||||
|
template<class T>
|
||||||
|
class iterable_event_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = T;
|
||||||
|
using const_iterator = const T;
|
||||||
|
protected:
|
||||||
|
iterator m_event;
|
||||||
|
public:
|
||||||
|
constexpr iterable_event_base(RJP_value* ev):
|
||||||
|
m_event(ev){}
|
||||||
|
constexpr iterable_event_base(const iterable_event_base& i):
|
||||||
|
m_event(i.m_event){}
|
||||||
|
constexpr const_iterator& begin(void)const{
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
constexpr iterator& begin(void){
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
constexpr const_iterator end(void)const{
|
||||||
|
return const_iterator(nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<class T>
|
||||||
|
class iterable_room_event_base
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = T;
|
||||||
|
using const_iterator = const T;
|
||||||
|
protected:
|
||||||
|
iterator m_event;
|
||||||
|
public:
|
||||||
|
constexpr iterable_room_event_base(RJP_value* ev, const raii::string_base& roomid):
|
||||||
|
m_event(ev, roomid){}
|
||||||
|
constexpr iterable_room_event_base(const iterable_room_event_base& i):
|
||||||
|
m_event(i.m_event){}
|
||||||
|
constexpr const_iterator& begin(void)const{
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
constexpr iterator& begin(void){
|
||||||
|
return m_event;
|
||||||
|
}
|
||||||
|
constexpr const_iterator end(void)const{
|
||||||
|
return const_iterator(nullptr, m_event.roomid());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class event_list : public iterable_event_base<detail::event_iterator<event>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterable_event_base<detail::event_iterator<event>>::iterable_event_base;
|
||||||
|
};
|
||||||
|
//Class representing a list of room state events
|
||||||
|
class room_state_event_list : public iterable_room_event_base<detail::room_event_iterator<room_state_event>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterable_room_event_base<detail::room_event_iterator<room_state_event>>::iterable_room_event_base;
|
||||||
|
};
|
||||||
|
//Class representing a list of room events
|
||||||
|
class room_event_list : public iterable_room_event_base<detail::room_event_iterator<room_event>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterable_room_event_base<detail::room_event_iterator<room_event>>::iterable_room_event_base;
|
||||||
|
};
|
||||||
|
//Class representing a list of room ephemeral events
|
||||||
|
class room_ephem_event_list : public iterable_room_event_base<detail::room_event_iterator<room_ephemeral_event>>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterable_room_event_base<detail::room_event_iterator<room_ephemeral_event>>::iterable_room_event_base;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -49,6 +49,9 @@ namespace matrix{
|
|||||||
const raii::string& invite(void)const;
|
const raii::string& invite(void)const;
|
||||||
const raii::string& room_members(void)const;
|
const raii::string& room_members(void)const;
|
||||||
const raii::string& upgrade(void)const;
|
const raii::string& upgrade(void)const;
|
||||||
|
raii::string messages(const raii::string_base& homeserver, const raii::string_base& access_token,
|
||||||
|
const raii::string_base& roomid, const raii::string_base& from, const raii::string_base& to,
|
||||||
|
const raii::string_base& dir, int limit)const;
|
||||||
|
|
||||||
void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid);
|
void repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid);
|
||||||
void invalidate_accesstoken(void);
|
void invalidate_accesstoken(void);
|
||||||
|
|||||||
@ -68,6 +68,9 @@ 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 raii::string_base& reason)const;
|
||||||
raii::rjp_string redact_event(const raii::string_base& eventid)const;
|
raii::rjp_string redact_event(const raii::string_base& eventid)const;
|
||||||
|
|
||||||
|
//recieve events
|
||||||
|
raii::string get_events_forward(int amount);
|
||||||
|
raii::string get_events_backward(int amount);
|
||||||
|
|
||||||
//meta stuff
|
//meta stuff
|
||||||
void regenerate_urls(void);
|
void regenerate_urls(void);
|
||||||
|
|||||||
156
include/matrix/sync_response.hpp
Normal file
156
include/matrix/sync_response.hpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of r0nk, atlas_moon, and rexy's matrix client
|
||||||
|
Copyright (C) 2019 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SYNC_RESPONSE_HPP
|
||||||
|
#define SYNC_RESPONSE_HPP
|
||||||
|
|
||||||
|
#include "raii/rjp_string.hpp"
|
||||||
|
#include "raii/static_string.hpp"
|
||||||
|
#include "raii/rjp_iterator.hpp"
|
||||||
|
#include "raii/rjp_ptr.hpp"
|
||||||
|
#include "matrix/events.hpp"
|
||||||
|
#include "matrix/iterable.hpp"
|
||||||
|
|
||||||
|
namespace matrix::sync{
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Class representing the "rooms" section of a sync response
|
||||||
|
*/
|
||||||
|
class room_event_response
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RJP_value* m_room;
|
||||||
|
public:
|
||||||
|
constexpr room_event_response(RJP_value* room):m_room(room){}
|
||||||
|
raii::static_string roomid(void)const;
|
||||||
|
room_event_list account_events(void);
|
||||||
|
room_ephem_event_list ephemeral_events(void);
|
||||||
|
room_state_event_list state_events(void);
|
||||||
|
room_state_event_list timeline_events(void);
|
||||||
|
RJP_value* notifications(void);
|
||||||
|
RJP_value* summary(void);
|
||||||
|
private:
|
||||||
|
RJP_value* _find_event_list(const char* mname)const;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class used to iterate over an array of rooms returned by a sync
|
||||||
|
*/
|
||||||
|
class room_iterator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
raii::rjp_object_iterator m_room;
|
||||||
|
public:
|
||||||
|
constexpr room_iterator(RJP_value* r):m_room(r){}
|
||||||
|
constexpr bool operator==(const room_iterator& r){
|
||||||
|
return r.m_room == m_room;
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const room_iterator& r){
|
||||||
|
return r.m_room != m_room;
|
||||||
|
}
|
||||||
|
room_iterator& operator++(void){
|
||||||
|
++m_room;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr room_event_response operator*(void){
|
||||||
|
return room_event_response(*m_room);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Class representing a list of rooms
|
||||||
|
*/
|
||||||
|
class room_list
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = room_iterator;
|
||||||
|
using const_iterator = const iterator;
|
||||||
|
private:
|
||||||
|
iterator m_room;
|
||||||
|
public:
|
||||||
|
constexpr room_list(RJP_value* room):m_room(room){}
|
||||||
|
constexpr room_list(const room_list& r):m_room(r.m_room){}
|
||||||
|
|
||||||
|
constexpr iterator& begin(void){
|
||||||
|
return m_room;
|
||||||
|
}
|
||||||
|
constexpr const_iterator& begin(void)const{
|
||||||
|
return m_room;
|
||||||
|
}
|
||||||
|
constexpr const_iterator end(void)const{
|
||||||
|
return const_iterator(nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class device_list
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
RJP_value* m_root;
|
||||||
|
public:
|
||||||
|
device_list(RJP_value* root):
|
||||||
|
m_root(root){}
|
||||||
|
event_list left(void)const{
|
||||||
|
return rjp_get_element(rjp_search_member(m_root, "left", 0).value);
|
||||||
|
}
|
||||||
|
event_list changed(void)const{
|
||||||
|
return rjp_get_element(rjp_search_member(m_root, "changed", 0).value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*
|
||||||
|
Class returned by a sync. Makes for theoretically easier processing than a pure raw response
|
||||||
|
*/
|
||||||
|
class response
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
raii::rjp_ptr m_root;
|
||||||
|
public:
|
||||||
|
response(const raii::string_base& src);
|
||||||
|
response(RJP_value* root);
|
||||||
|
|
||||||
|
room_list room_join_events(void)const;
|
||||||
|
room_list room_invite_events(void)const;
|
||||||
|
room_list room_leave_events(void)const;
|
||||||
|
|
||||||
|
device_list device_lists(void)const;
|
||||||
|
raii::static_string next_batch(void)const&;
|
||||||
|
raii::rjp_string next_batch(void)&&;
|
||||||
|
|
||||||
|
event_list to_device_events(void)const;
|
||||||
|
event_list presence_events(void)const;
|
||||||
|
event_list account_data_events(void)const;
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
room_list groups_join_events(void)const;
|
||||||
|
room_list groups_leave_events(void)const;
|
||||||
|
room_list group_invite_events(void)const;
|
||||||
|
RJP_value* device_one_time_keys_count(void)const;
|
||||||
|
|
||||||
|
RJP_value* raw_handle(void);
|
||||||
|
const RJP_value* raw_handle(void)const;
|
||||||
|
raii::rjp_string raw_str(void)const;
|
||||||
|
private:
|
||||||
|
RJP_value* _find_room_list(const char* segment)const;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -24,6 +24,7 @@
|
|||||||
#include "raii/string.hpp"
|
#include "raii/string.hpp"
|
||||||
#include "matrix/session_info.hpp"
|
#include "matrix/session_info.hpp"
|
||||||
#include "matrix/connection.hpp"
|
#include "matrix/connection.hpp"
|
||||||
|
#include "matrix/sync_response.hpp"
|
||||||
#include <cstdlib> //size_t
|
#include <cstdlib> //size_t
|
||||||
#include <memory> //shared_ptr
|
#include <memory> //shared_ptr
|
||||||
|
|
||||||
@ -54,7 +55,7 @@ namespace matrix{
|
|||||||
* Sync state with the homeserver. Will wait for up to timeout ms.
|
* Sync state with the homeserver. Will wait for up to timeout ms.
|
||||||
* Returns: the raw json response from the homeserver.
|
* Returns: the raw json response from the homeserver.
|
||||||
*/
|
*/
|
||||||
raii::string sync(size_t timeout);
|
sync::response sync(size_t timeout);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
85
include/raii/rjp_iterator.hpp
Normal file
85
include/raii/rjp_iterator.hpp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#ifndef RJP_ITERATOR_HPP
|
||||||
|
#define RJP_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <rjp.h>
|
||||||
|
|
||||||
|
namespace raii{
|
||||||
|
|
||||||
|
class rjp_object_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = RJP_value*;
|
||||||
|
using const_iterator = const iterator;
|
||||||
|
private:
|
||||||
|
RJP_value* m_value;
|
||||||
|
public:
|
||||||
|
constexpr rjp_object_iterator(RJP_value* v):m_value(v){}
|
||||||
|
constexpr rjp_object_iterator(const rjp_object_iterator& e):m_value(e.m_value){}
|
||||||
|
constexpr rjp_object_iterator& operator=(const rjp_object_iterator& e){
|
||||||
|
m_value = e.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr bool operator==(const rjp_object_iterator& e)const{
|
||||||
|
return m_value == e.m_value;
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const rjp_object_iterator& e)const{
|
||||||
|
return m_value != e.m_value;
|
||||||
|
}
|
||||||
|
rjp_object_iterator& operator++(void){
|
||||||
|
m_value = rjp_next_member(m_value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr RJP_value* operator*(void){
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
constexpr const RJP_value* operator*(void)const{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
constexpr RJP_value& operator->(void){
|
||||||
|
return *m_value;
|
||||||
|
}
|
||||||
|
constexpr const RJP_value& operator->(void)const{
|
||||||
|
return *m_value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
class rjp_array_iterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using iterator = RJP_value*;
|
||||||
|
using const_iterator = const iterator;
|
||||||
|
private:
|
||||||
|
RJP_value* m_value;
|
||||||
|
public:
|
||||||
|
constexpr rjp_array_iterator(RJP_value* v):m_value(v){}
|
||||||
|
constexpr rjp_array_iterator(const rjp_array_iterator& e):m_value(e.m_value){}
|
||||||
|
constexpr rjp_array_iterator& operator=(const rjp_array_iterator& e){
|
||||||
|
m_value = e.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr bool operator==(const rjp_array_iterator& e)const{
|
||||||
|
return m_value == e.m_value;
|
||||||
|
}
|
||||||
|
constexpr bool operator!=(const rjp_array_iterator& e)const{
|
||||||
|
return m_value != e.m_value;
|
||||||
|
}
|
||||||
|
rjp_array_iterator& operator++(void){
|
||||||
|
m_value = rjp_next_element(m_value);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
constexpr RJP_value* operator*(void){
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
constexpr const RJP_value* operator*(void)const{
|
||||||
|
return m_value;
|
||||||
|
}
|
||||||
|
constexpr RJP_value& operator->(void){
|
||||||
|
return *m_value;
|
||||||
|
}
|
||||||
|
constexpr const RJP_value& operator->(void)const{
|
||||||
|
return *m_value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -104,10 +104,10 @@ namespace raii{
|
|||||||
char* release(void);
|
char* release(void);
|
||||||
|
|
||||||
//Length of string not including null terminator
|
//Length of string not including null terminator
|
||||||
size_t length(void)const;
|
constexpr size_t length(void)const{return m_length;}
|
||||||
//direct access to managed pointer
|
//direct access to managed pointer
|
||||||
char* get(void);
|
constexpr char* get(void){return m_data;}
|
||||||
const char* get(void)const;
|
constexpr const char* get(void)const{return m_data;}
|
||||||
operator char*(void);
|
operator char*(void);
|
||||||
operator const char*(void)const;
|
operator const char*(void)const;
|
||||||
//true if m_data is not null
|
//true if m_data is not null
|
||||||
|
|||||||
109
src/matrix/events.cpp
Normal file
109
src/matrix/events.cpp
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of r0nk, atlas_moon, and rexy's matrix client
|
||||||
|
Copyright (C) 2019 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "matrix/events.hpp"
|
||||||
|
|
||||||
|
namespace matrix::sync{
|
||||||
|
|
||||||
|
//Event base
|
||||||
|
raii::static_string event::type(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "type", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string event::type(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "type", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
const RJP_value* event::content(void)const{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "content", 0);
|
||||||
|
return res.value;
|
||||||
|
}
|
||||||
|
RJP_value* event::content(void){
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "content", 0);
|
||||||
|
return res.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Room event
|
||||||
|
raii::static_string room_event::eventid(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "event_id", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string room_event::eventid(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "event_id", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
raii::static_string room_event::sender(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "sender", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string room_event::sender(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "sender", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
int room_event::origin_server_ts(void)const{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "origin_server_ts", 0);
|
||||||
|
return rjp_value_integer(res.value);
|
||||||
|
}
|
||||||
|
const RJP_value* room_event::extra(void)const{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "unsigned", 0);
|
||||||
|
return res.value;
|
||||||
|
}
|
||||||
|
RJP_value* room_event::extra(void){
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "unsigned", 0);
|
||||||
|
return res.value;
|
||||||
|
}
|
||||||
|
raii::static_string room_event::redacts(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "redacts", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string room_event::redacts(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "redacts", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Room state event
|
||||||
|
raii::static_string room_state_event::state_key(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "state_key", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string room_state_event::state_key(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "state_key", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
raii::static_string room_state_event::prev_content(void)const&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "prev_content", 0);
|
||||||
|
if(res.value)
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
res = rjp_search_member(m_event, "unsigned", 0);
|
||||||
|
if(!res.value)
|
||||||
|
return raii::static_string{};
|
||||||
|
res = rjp_search_member(res.value, "prev_content", 0);
|
||||||
|
return raii::static_string(rjp_value_string(res.value), rjp_value_string_length(res.value));
|
||||||
|
}
|
||||||
|
raii::rjp_string room_state_event::prev_content(void)&&{
|
||||||
|
RJP_search_res res = rjp_search_member(m_event, "prev_content", 0);
|
||||||
|
if(res.value)
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
res = rjp_search_member(m_event, "unsigned", 0);
|
||||||
|
if(!res.value)
|
||||||
|
return raii::static_string{};
|
||||||
|
res = rjp_search_member(res.value, "prev_content", 0);
|
||||||
|
return raii::rjp_string(res.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "matrix/room_url_list.hpp"
|
#include "matrix/room_url_list.hpp"
|
||||||
|
#include "raii/util.hpp"
|
||||||
|
|
||||||
namespace matrix{
|
namespace matrix{
|
||||||
|
|
||||||
@ -69,6 +70,15 @@ namespace matrix{
|
|||||||
const raii::string& room_url_list::upgrade(void)const{
|
const raii::string& room_url_list::upgrade(void)const{
|
||||||
return m_upgrade;
|
return m_upgrade;
|
||||||
}
|
}
|
||||||
|
raii::string room_url_list::messages(const raii::string_base& homeserver, const raii::string_base& access_token,
|
||||||
|
const raii::string_base& roomid, const raii::string_base& from, const raii::string_base& to,
|
||||||
|
const raii::string_base& dir, int limit)const
|
||||||
|
{
|
||||||
|
if(to)
|
||||||
|
return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/messages?from=" + from + "&to=" + to + "&limit=" + raii::itostr(limit) + "&dir=" + dir + "&access_token=" + access_token);
|
||||||
|
else
|
||||||
|
return raii::string(s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/messages?from=" + from + "&limit=" + raii::itostr(limit) + "&dir=" + dir + "&access_token=" + access_token);
|
||||||
|
}
|
||||||
void room_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid){
|
void room_url_list::repopulate(const raii::string_base& homeserver, const raii::string_base& access_token, const raii::string_base& userid, const raii::string_base& roomid){
|
||||||
m_join = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/join?access_token=" + access_token;
|
m_join = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/join?access_token=" + access_token;
|
||||||
m_leave = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/leave?access_token=" + access_token;
|
m_leave = s_proto + homeserver + "/_matrix/client/r0/rooms/" + roomid + "/leave?access_token=" + access_token;
|
||||||
|
|||||||
@ -109,6 +109,12 @@ namespace matrix{
|
|||||||
raii::rjp_string roomcxn::redact_event(const raii::string_base& eventid)const{
|
raii::rjp_string roomcxn::redact_event(const raii::string_base& eventid)const{
|
||||||
return redact_event(eventid, "No reason given"_ss);
|
return redact_event(eventid, "No reason given"_ss);
|
||||||
}
|
}
|
||||||
|
raii::string roomcxn::get_events_forward(int amount){
|
||||||
|
return _get_curl(m_urls.messages(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), ""_ss, raii::static_string(), "f"_ss, amount));
|
||||||
|
}
|
||||||
|
raii::string roomcxn::get_events_backward(int amount){
|
||||||
|
return _get_curl(m_urls.messages(m_ses->homeserver, m_ses->access_token, m_curl.encode(m_roomid), ""_ss, raii::static_string(), "b"_ss, amount));
|
||||||
|
}
|
||||||
|
|
||||||
void roomcxn::regenerate_urls(void){
|
void roomcxn::regenerate_urls(void){
|
||||||
m_urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid, m_roomid);
|
m_urls.repopulate(m_ses->homeserver, m_ses->access_token, m_ses->userid, m_roomid);
|
||||||
|
|||||||
108
src/matrix/sync_response.cpp
Normal file
108
src/matrix/sync_response.cpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/**
|
||||||
|
This file is a part of r0nk, atlas_moon, and rexy's matrix client
|
||||||
|
Copyright (C) 2019 rexy712
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "matrix/sync_response.hpp"
|
||||||
|
|
||||||
|
namespace matrix::sync{
|
||||||
|
|
||||||
|
//Room event response
|
||||||
|
raii::static_string room_event_response::roomid(void)const{
|
||||||
|
return raii::static_string(rjp_member_name(m_room), rjp_member_name_length(m_room));
|
||||||
|
}
|
||||||
|
RJP_value* room_event_response::_find_event_list(const char* mname)const{
|
||||||
|
RJP_search_res res = rjp_search_member(m_room, mname, 0);
|
||||||
|
if(!res.value)
|
||||||
|
return nullptr;
|
||||||
|
res = rjp_search_member(res.value, "events", 0);
|
||||||
|
if(!res.value)
|
||||||
|
return nullptr;
|
||||||
|
return rjp_get_element(res.value);
|
||||||
|
}
|
||||||
|
room_event_list room_event_response::account_events(void){
|
||||||
|
return room_event_list(_find_event_list("account_data"), roomid());
|
||||||
|
}
|
||||||
|
room_ephem_event_list room_event_response::ephemeral_events(void){
|
||||||
|
return room_ephem_event_list(_find_event_list("ephemeral"), roomid());
|
||||||
|
}
|
||||||
|
room_state_event_list room_event_response::state_events(void){
|
||||||
|
return room_state_event_list(_find_event_list("state"), roomid());
|
||||||
|
}
|
||||||
|
room_state_event_list room_event_response::timeline_events(void){
|
||||||
|
return room_state_event_list(_find_event_list("timeline"), roomid());
|
||||||
|
}
|
||||||
|
RJP_value* room_event_response::notifications(void){
|
||||||
|
return rjp_search_member(m_room, "unread_notifications", 0).value;
|
||||||
|
}
|
||||||
|
RJP_value* room_event_response::summary(void){
|
||||||
|
return rjp_search_member(m_room, "summary", 0).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Sync response
|
||||||
|
response::response(const raii::string_base& s):
|
||||||
|
m_root(rjp_parse(s)){}
|
||||||
|
response::response(RJP_value* root):
|
||||||
|
m_root(root){}
|
||||||
|
room_list response::room_join_events(void)const{
|
||||||
|
return _find_room_list("join");
|
||||||
|
}
|
||||||
|
room_list response::room_invite_events(void)const{
|
||||||
|
return _find_room_list("invite");
|
||||||
|
}
|
||||||
|
room_list response::room_leave_events(void)const{
|
||||||
|
return _find_room_list("leave");
|
||||||
|
}
|
||||||
|
device_list response::device_lists(void)const{
|
||||||
|
return rjp_search_member(m_root.get(), "device_lists", 0).value;
|
||||||
|
}
|
||||||
|
raii::static_string response::next_batch(void)const&{
|
||||||
|
RJP_value* nb = rjp_search_member(m_root.get(), "next_batch", 0).value;
|
||||||
|
if(!nb) return {};
|
||||||
|
return raii::static_string(rjp_value_string(nb), rjp_value_string_length(nb));
|
||||||
|
}
|
||||||
|
raii::rjp_string response::next_batch(void)&&{
|
||||||
|
return raii::rjp_string(rjp_search_member(m_root.get(), "next_batch", 0).value);
|
||||||
|
}
|
||||||
|
event_list response::to_device_events(void)const{
|
||||||
|
return rjp_search_member(rjp_search_member(m_root.get(), "to_device", 0).value, "events", 0).value;
|
||||||
|
}
|
||||||
|
event_list response::presence_events(void)const{
|
||||||
|
return rjp_search_member(rjp_search_member(m_root.get(), "presence", 0).value, "events", 0).value;
|
||||||
|
}
|
||||||
|
RJP_value* response::device_one_time_keys_count(void)const{
|
||||||
|
return rjp_search_member(m_root.get(), "device_one_time_keys_count", 0).value;
|
||||||
|
}
|
||||||
|
|
||||||
|
RJP_value* response::raw_handle(void){
|
||||||
|
return m_root.get();
|
||||||
|
}
|
||||||
|
const RJP_value* response::raw_handle(void)const{
|
||||||
|
return m_root.get();
|
||||||
|
}
|
||||||
|
raii::rjp_string response::raw_str(void)const{
|
||||||
|
return raii::rjp_string(rjp_to_json(m_root.get()));
|
||||||
|
}
|
||||||
|
RJP_value* response::_find_room_list(const char* segment)const{
|
||||||
|
RJP_search_res res = rjp_search_member(m_root.get(), "rooms", 0);
|
||||||
|
if(!res.value)
|
||||||
|
return {nullptr};
|
||||||
|
res = rjp_search_member(res.value, segment, 0);
|
||||||
|
if(!res.value)
|
||||||
|
return {nullptr};
|
||||||
|
return {rjp_get_member(res.value)};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -25,11 +25,11 @@ namespace matrix{
|
|||||||
syncer::syncer(const std::shared_ptr<internal::session_info>& ses):
|
syncer::syncer(const std::shared_ptr<internal::session_info>& ses):
|
||||||
connection(ses){}
|
connection(ses){}
|
||||||
|
|
||||||
raii::string syncer::sync(size_t timeout){
|
sync::response syncer::sync(size_t timeout){
|
||||||
raii::string reply = _get_curl(m_ses->urls.sync(m_ses->homeserver, m_ses->access_token, m_next_batch, raii::itostr(timeout)));
|
raii::string reply = _get_curl(m_ses->urls.sync(m_ses->homeserver, m_ses->access_token, m_next_batch, raii::itostr(timeout)));
|
||||||
|
|
||||||
if(!reply)
|
if(!reply)
|
||||||
return {};
|
return {nullptr};
|
||||||
raii::rjp_ptr root(rjp_parse(reply));
|
raii::rjp_ptr root(rjp_parse(reply));
|
||||||
if(!root)
|
if(!root)
|
||||||
return reply;
|
return reply;
|
||||||
@ -38,7 +38,6 @@ namespace matrix{
|
|||||||
if(!res.value)
|
if(!res.value)
|
||||||
return reply;
|
return reply;
|
||||||
m_next_batch = res.value;
|
m_next_batch = res.value;
|
||||||
|
return sync::response(root.release());
|
||||||
return reply;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,15 +39,6 @@ namespace raii{
|
|||||||
m_length = val ? strlen(val) : 0;
|
m_length = val ? strlen(val) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t string_base::length(void)const{
|
|
||||||
return m_length;
|
|
||||||
}
|
|
||||||
char* string_base::get(void){
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
const char* string_base::get(void)const{
|
|
||||||
return m_data;
|
|
||||||
}
|
|
||||||
string_base::operator bool(void)const{
|
string_base::operator bool(void)const{
|
||||||
return m_data;
|
return m_data;
|
||||||
}
|
}
|
||||||
|
|||||||
23
src/test.cpp
23
src/test.cpp
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "matrix/matrix.hpp"
|
#include "matrix/matrix.hpp"
|
||||||
#include "raii/static_string.hpp"
|
#include "raii/static_string.hpp"
|
||||||
|
#include "matrix/sync_response.hpp"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@ -27,11 +28,18 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
|
||||||
void sync_fn(matrix::syncer syn, std::atomic_bool& should_quit){
|
void sync_fn(matrix::syncer syn, std::atomic_bool& should_quit){
|
||||||
auto sync_reply = syn.sync(0);
|
syn.sync(0);
|
||||||
|
|
||||||
|
printf("paused\n");
|
||||||
|
getchar();
|
||||||
|
printf("continuing\n");
|
||||||
while(!should_quit){
|
while(!should_quit){
|
||||||
sync_reply = syn.sync(30000);
|
auto sync_reply = syn.sync(30000);
|
||||||
printf("%s\n", sync_reply.get());
|
for(auto room : sync_reply.room_join_events()){
|
||||||
|
for(auto event : room.timeline_events()){
|
||||||
|
printf("%s\n", event.sender().get());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,10 +71,15 @@ int main(){
|
|||||||
|
|
||||||
std::atomic_bool should_quit = false;
|
std::atomic_bool should_quit = false;
|
||||||
|
|
||||||
|
auto syn = ses.spawn_syncer();
|
||||||
|
syn.sync(0);
|
||||||
|
|
||||||
|
//auto room = ses.spawn_client().spawn_room("!OwuhlJnHlsmyPwiLIH:rexy712.chickenkiller.com"_ss);
|
||||||
|
//printf("%s\n", room.get_events_backward(1).get());
|
||||||
std::thread sync_thread(sync_fn, ses.spawn_syncer(), std::ref(should_quit));
|
std::thread sync_thread(sync_fn, ses.spawn_syncer(), std::ref(should_quit));
|
||||||
std::thread key_thread(keyboard_fn, ses.spawn_client().spawn_room("!cEIFONpAlHTbGBUFAE:rexy712.chickenkiller.com"_ss), std::ref(should_quit));
|
//std::thread key_thread(keyboard_fn, ses.spawn_client().spawn_room("!cEIFONpAlHTbGBUFAE:rexy712.chickenkiller.com"_ss), std::ref(should_quit));
|
||||||
|
|
||||||
//one of these threads will always hang until another input is recieved
|
//one of these threads will always hang until another input is recieved
|
||||||
sync_thread.join();
|
sync_thread.join();
|
||||||
key_thread.join();
|
//key_thread.join();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user