bug fixes, parents, root node, topic, etc
This commit is contained in:
parent
0379c8a5ab
commit
0be741947c
@ -52,11 +52,11 @@ target_link_libraries(solanaceae_ircclient_messages PUBLIC
|
|||||||
|
|
||||||
########################################
|
########################################
|
||||||
|
|
||||||
add_executable(test2 EXCLUDE_FROM_ALL
|
add_executable(irc_test2 EXCLUDE_FROM_ALL
|
||||||
test2.cpp
|
test2.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(test2 PUBLIC
|
target_link_libraries(irc_test2 PUBLIC
|
||||||
solanaceae_ircclient
|
solanaceae_ircclient
|
||||||
solanaceae_ircclient_contacts
|
solanaceae_ircclient_contacts
|
||||||
solanaceae_ircclient_messages
|
solanaceae_ircclient_messages
|
||||||
|
@ -12,7 +12,7 @@ extern "C" void* irc_get_ctx(irc_session_t* session);
|
|||||||
|
|
||||||
namespace IRCClient::Events {
|
namespace IRCClient::Events {
|
||||||
|
|
||||||
// TODO: proper param seperation
|
// TODO: proper param separation
|
||||||
|
|
||||||
struct Numeric {
|
struct Numeric {
|
||||||
unsigned int event;
|
unsigned int event;
|
||||||
|
@ -26,6 +26,7 @@ IRCClientContactModel::IRCClientContactModel(
|
|||||||
|
|
||||||
_ircc.subscribe(this, IRCClient_Event::JOIN);
|
_ircc.subscribe(this, IRCClient_Event::JOIN);
|
||||||
_ircc.subscribe(this, IRCClient_Event::PART);
|
_ircc.subscribe(this, IRCClient_Event::PART);
|
||||||
|
_ircc.subscribe(this, IRCClient_Event::TOPIC);
|
||||||
_ircc.subscribe(this, IRCClient_Event::QUIT);
|
_ircc.subscribe(this, IRCClient_Event::QUIT);
|
||||||
|
|
||||||
_ircc.subscribe(this, IRCClient_Event::CTCP_REQ);
|
_ircc.subscribe(this, IRCClient_Event::CTCP_REQ);
|
||||||
@ -65,13 +66,21 @@ std::vector<uint8_t> IRCClientContactModel::getHash(std::string_view value) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> IRCClientContactModel::getHash(const std::vector<uint8_t>& value) {
|
||||||
|
assert(!value.empty());
|
||||||
|
|
||||||
|
std::vector<uint8_t> hash(crypto_hash_sha256_bytes(), 0x00);
|
||||||
|
crypto_hash_sha256(hash.data(), value.data(), value.size());
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> IRCClientContactModel::getIDHash(std::string_view name) {
|
std::vector<uint8_t> IRCClientContactModel::getIDHash(std::string_view name) {
|
||||||
assert(!_server_hash.empty());
|
assert(!_server_hash.empty());
|
||||||
assert(!name.empty());
|
assert(!name.empty());
|
||||||
|
|
||||||
std::vector<uint8_t> data = _server_hash;
|
std::vector<uint8_t> data = _server_hash;
|
||||||
data.insert(data.end(), name.begin(), name.end());
|
data.insert(data.end(), name.begin(), name.end());
|
||||||
return getHash(std::string_view{reinterpret_cast<const char*>(data.data()), data.size()});
|
return getHash(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Contact3Handle IRCClientContactModel::getC(std::string_view channel) {
|
Contact3Handle IRCClientContactModel::getC(std::string_view channel) {
|
||||||
@ -148,6 +157,9 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Connect& e) {
|
|||||||
_cr.emplace_or_replace<Contact::Components::ConnectionState>(_server, Contact::Components::ConnectionState::State::direct);
|
_cr.emplace_or_replace<Contact::Components::ConnectionState>(_server, Contact::Components::ConnectionState::State::direct);
|
||||||
|
|
||||||
_cr.emplace_or_replace<Contact::Components::TagBig>(_server);
|
_cr.emplace_or_replace<Contact::Components::TagBig>(_server);
|
||||||
|
// the server connection is also the root contact (ircccm only handles 1 server 1 user)
|
||||||
|
_cr.emplace_or_replace<Contact::Components::TagRoot>(_server);
|
||||||
|
// TODO: should this be its own node instead? or should the server node be created on construction?
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // self
|
{ // self
|
||||||
@ -159,16 +171,17 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Connect& e) {
|
|||||||
// check for empty contact by id
|
// check for empty contact by id
|
||||||
for (const auto e : _cr.view<Contact::Components::ID>()) {
|
for (const auto e : _cr.view<Contact::Components::ID>()) {
|
||||||
if (_cr.get<Contact::Components::ID>(e).data == self_hash) {
|
if (_cr.get<Contact::Components::ID>(e).data == self_hash) {
|
||||||
_server = e;
|
_self = e;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!_cr.valid(_server)) {
|
if (!_cr.valid(_self)) {
|
||||||
_self = _cr.create();
|
_self = _cr.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_cr.emplace_or_replace<Contact::Components::ContactModel>(_self, this);
|
_cr.emplace_or_replace<Contact::Components::ContactModel>(_self, this);
|
||||||
|
_cr.emplace_or_replace<Contact::Components::Parent>(_self, _server);
|
||||||
_cr.emplace_or_replace<Contact::Components::TagSelfStrong>(_self);
|
_cr.emplace_or_replace<Contact::Components::TagSelfStrong>(_self);
|
||||||
_cr.emplace_or_replace<Contact::Components::IRC::ServerName>(_self, std::string{_ircc.getServerName()}); // really?
|
_cr.emplace_or_replace<Contact::Components::IRC::ServerName>(_self, std::string{_ircc.getServerName()}); // really?
|
||||||
if (!e.params.empty()) {
|
if (!e.params.empty()) {
|
||||||
@ -177,9 +190,18 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Connect& e) {
|
|||||||
// make id hash(hash(ServerName)+UserName)
|
// make id hash(hash(ServerName)+UserName)
|
||||||
// or irc name format, but those might cause collisions
|
// or irc name format, but those might cause collisions
|
||||||
_cr.emplace_or_replace<Contact::Components::ID>(_self, getIDHash(e.params.front()));
|
_cr.emplace_or_replace<Contact::Components::ID>(_self, getIDHash(e.params.front()));
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
std::cout << "### created self with"
|
||||||
|
<< " e:" << entt::to_integral(_self)
|
||||||
|
<< " ircn:" << _cr.get<Contact::Components::IRC::UserName>(_self).name
|
||||||
|
<< " ircsn:" << _cr.get<Contact::Components::IRC::ServerName>(_self).name
|
||||||
|
<< " id:" << bin2hex(_cr.get<Contact::Components::ID>(_self).data)
|
||||||
|
<< "\n";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
_cr.emplace_or_replace<Contact::Components::ConnectionState>(_self, Contact::Components::ConnectionState::State::cloud);
|
_cr.emplace_or_replace<Contact::Components::ConnectionState>(_self, Contact::Components::ConnectionState::State::direct);
|
||||||
|
|
||||||
// add self to server
|
// add self to server
|
||||||
_cr.emplace_or_replace<Contact::Components::Self>(_server, _self);
|
_cr.emplace_or_replace<Contact::Components::Self>(_server, _self);
|
||||||
@ -211,15 +233,19 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Numeric& e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.params.at(1) != "=") {
|
if (
|
||||||
// error, unexpected
|
e.params.at(1) != "=" && // Public channel
|
||||||
|
e.params.at(1) != "@" && // Secret channel
|
||||||
|
e.params.at(1) != "*" // Private channel
|
||||||
|
) {
|
||||||
|
std::cerr << "IRCCCM error: name list for unknown channel type\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& channel_name = e.params.at(2);
|
const auto& channel_name = e.params.at(2);
|
||||||
auto channel = getC(channel_name);
|
auto channel = getC(channel_name);
|
||||||
if (!channel.valid()) {
|
if (!channel.valid()) {
|
||||||
std::cerr << "IRCCM error: name list for unknown channel\n";
|
std::cerr << "IRCCCM error: name list for unknown channel\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +257,7 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Numeric& e) {
|
|||||||
auto user_str = user_list.substr(0, space_pos);
|
auto user_str = user_list.substr(0, space_pos);
|
||||||
{ // handle user
|
{ // handle user
|
||||||
// rfc 2812 5.1
|
// rfc 2812 5.1
|
||||||
// The '@' and '+' characters next to the channel name
|
// The '@' and '+' characters next to the user name
|
||||||
// indicate whether a client is a channel operator or
|
// indicate whether a client is a channel operator or
|
||||||
// has been granted permission to speak on a moderated
|
// has been granted permission to speak on a moderated
|
||||||
// channel.
|
// channel.
|
||||||
@ -317,6 +343,27 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Numeric& e) {
|
|||||||
}
|
}
|
||||||
user_list = user_list.substr(next_non_space);
|
user_list = user_list.substr(next_non_space);
|
||||||
} while (space_pos != std::string_view::npos);
|
} while (space_pos != std::string_view::npos);
|
||||||
|
} else if (e.event == LIBIRC_RFC_RPL_TOPIC) {
|
||||||
|
// origin is the server
|
||||||
|
// params.at(0) is the user (self)
|
||||||
|
// params.at(1) is the channel
|
||||||
|
// params.at(2) is the topic
|
||||||
|
if (e.params.size() != 3) {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: check user (self)
|
||||||
|
|
||||||
|
const auto channel_name = e.params.at(1);
|
||||||
|
auto channel = getC(channel_name);
|
||||||
|
if (!channel.valid()) {
|
||||||
|
std::cerr << "IRCCCM error: topic for unknown channel\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto topic = e.params.at(2);
|
||||||
|
channel.emplace_or_replace<Contact::Components::StatusText>(std::string{topic}).fillFirstLineLength();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -345,6 +392,8 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Join& e) {
|
|||||||
channel.emplace_or_replace<Contact::Components::ID>(channel_hash);
|
channel.emplace_or_replace<Contact::Components::ID>(channel_hash);
|
||||||
}
|
}
|
||||||
channel.emplace_or_replace<Contact::Components::ContactModel>(this);
|
channel.emplace_or_replace<Contact::Components::ContactModel>(this);
|
||||||
|
channel.emplace_or_replace<Contact::Components::Parent>(_server);
|
||||||
|
channel.emplace_or_replace<Contact::Components::ParentOf>(); // start empty
|
||||||
channel.emplace_or_replace<Contact::Components::IRC::ServerName>(std::string{_ircc.getServerName()});
|
channel.emplace_or_replace<Contact::Components::IRC::ServerName>(std::string{_ircc.getServerName()});
|
||||||
channel.emplace_or_replace<Contact::Components::IRC::ChannelName>(std::string{joined_channel_name});
|
channel.emplace_or_replace<Contact::Components::IRC::ChannelName>(std::string{joined_channel_name});
|
||||||
channel.emplace_or_replace<Contact::Components::Name>(std::string{joined_channel_name});
|
channel.emplace_or_replace<Contact::Components::Name>(std::string{joined_channel_name});
|
||||||
@ -354,6 +403,7 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Join& e) {
|
|||||||
channel.emplace_or_replace<Contact::Components::ConnectionState>(Contact::Components::ConnectionState::State::cloud);
|
channel.emplace_or_replace<Contact::Components::ConnectionState>(Contact::Components::ConnectionState::State::cloud);
|
||||||
|
|
||||||
channel.emplace_or_replace<Contact::Components::TagBig>();
|
channel.emplace_or_replace<Contact::Components::TagBig>();
|
||||||
|
channel.emplace_or_replace<Contact::Components::TagGroup>();
|
||||||
|
|
||||||
// add self to channel
|
// add self to channel
|
||||||
channel.emplace_or_replace<Contact::Components::Self>(_self);
|
channel.emplace_or_replace<Contact::Components::Self>(_self);
|
||||||
@ -372,14 +422,22 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Join& e) {
|
|||||||
if (!user.valid()) {
|
if (!user.valid()) {
|
||||||
user = {_cr, _cr.create()};
|
user = {_cr, _cr.create()};
|
||||||
user.emplace_or_replace<Contact::Components::ID>(user_hash);
|
user.emplace_or_replace<Contact::Components::ID>(user_hash);
|
||||||
|
std::cerr << "IRCCCM error: had to create joining user (self?)\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
user.emplace_or_replace<Contact::Components::ContactModel>(this);
|
user.emplace_or_replace<Contact::Components::ContactModel>(this);
|
||||||
|
user.emplace_or_replace<Contact::Components::Parent>(_server);
|
||||||
user.emplace_or_replace<Contact::Components::IRC::ServerName>(std::string{_ircc.getServerName()});
|
user.emplace_or_replace<Contact::Components::IRC::ServerName>(std::string{_ircc.getServerName()});
|
||||||
// channel list?
|
// channel list?
|
||||||
// add to channel?
|
// add to channel?
|
||||||
user.emplace_or_replace<Contact::Components::IRC::UserName>(std::string{e.origin});
|
user.emplace_or_replace<Contact::Components::IRC::UserName>(std::string{e.origin});
|
||||||
user.emplace_or_replace<Contact::Components::Name>(std::string{e.origin});
|
user.emplace_or_replace<Contact::Components::Name>(std::string{e.origin});
|
||||||
|
|
||||||
|
std::cout << "### created self(?) with"
|
||||||
|
<< " ircn:" << _cr.get<Contact::Components::IRC::UserName>(_self).name
|
||||||
|
<< " ircsn:" << _cr.get<Contact::Components::IRC::ServerName>(_self).name
|
||||||
|
<< " id:" << bin2hex(_cr.get<Contact::Components::ID>(_self).data)
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.entity() != _self) {
|
if (user.entity() != _self) {
|
||||||
@ -433,6 +491,29 @@ bool IRCClientContactModel::onEvent(const IRCClient::Events::Part& e) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IRCClientContactModel::onEvent(const IRCClient::Events::Topic& e) {
|
||||||
|
// sadly only fired on topic change
|
||||||
|
|
||||||
|
// origin is user (setter)
|
||||||
|
// params.at(0) is channel
|
||||||
|
// params.at(1) is new topic
|
||||||
|
if (e.params.size() != 2) {
|
||||||
|
// error
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto channel_name = e.params.at(0);
|
||||||
|
auto channel = getC(channel_name);
|
||||||
|
if (!channel.valid()) {
|
||||||
|
std::cerr << "IRCCCM error: new topic for unknown channel\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto topic = e.params.at(1);
|
||||||
|
channel.emplace_or_replace<Contact::Components::StatusText>(std::string{topic}).fillFirstLineLength();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool IRCClientContactModel::onEvent(const IRCClient::Events::Quit& e) {
|
bool IRCClientContactModel::onEvent(const IRCClient::Events::Quit& e) {
|
||||||
// e.origin // is the quitting user
|
// e.origin // is the quitting user
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@ class IRCClientContactModel : public IRCClientEventI, public ContactModel3I {
|
|||||||
private:
|
private:
|
||||||
// just the hash algo
|
// just the hash algo
|
||||||
std::vector<uint8_t> getHash(std::string_view value);
|
std::vector<uint8_t> getHash(std::string_view value);
|
||||||
|
std::vector<uint8_t> getHash(const std::vector<uint8_t>& value);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// the actually ID is a chain containing the server+channel or server+name
|
// the actually ID is a chain containing the server+channel or server+name
|
||||||
@ -57,6 +58,7 @@ class IRCClientContactModel : public IRCClientEventI, public ContactModel3I {
|
|||||||
bool onEvent(const IRCClient::Events::Numeric& e) override;
|
bool onEvent(const IRCClient::Events::Numeric& e) override;
|
||||||
bool onEvent(const IRCClient::Events::Join& e) override;
|
bool onEvent(const IRCClient::Events::Join& e) override;
|
||||||
bool onEvent(const IRCClient::Events::Part& e) override;
|
bool onEvent(const IRCClient::Events::Part& e) override;
|
||||||
|
bool onEvent(const IRCClient::Events::Topic& e) override;
|
||||||
bool onEvent(const IRCClient::Events::Quit& e) override;
|
bool onEvent(const IRCClient::Events::Quit& e) override;
|
||||||
bool onEvent(const IRCClient::Events::CTCP_Req&) override;
|
bool onEvent(const IRCClient::Events::CTCP_Req&) override;
|
||||||
};
|
};
|
||||||
|
@ -16,12 +16,6 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
//namespace Components {
|
|
||||||
//struct ServerName {
|
|
||||||
//std::string name;
|
|
||||||
//};
|
|
||||||
//} // Components
|
|
||||||
|
|
||||||
IRCClientMessageManager::IRCClientMessageManager(
|
IRCClientMessageManager::IRCClientMessageManager(
|
||||||
RegistryMessageModel& rmm,
|
RegistryMessageModel& rmm,
|
||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
@ -207,19 +201,21 @@ bool IRCClientMessageManager::onEvent(const IRCClient::Events::PrivMSG& e) {
|
|||||||
// e.origin is sender
|
// e.origin is sender
|
||||||
auto from = _ircccm.getU(e.origin); // assuming its always a user // aka ContactFrom
|
auto from = _ircccm.getU(e.origin); // assuming its always a user // aka ContactFrom
|
||||||
if (!from.valid()) {
|
if (!from.valid()) {
|
||||||
std::cerr << "IRCCMM error: channel event unknown sender\n";
|
std::cerr << "IRCCMM error: privmsg event unknown sender\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// e.params.at(0) is receiver (us?)
|
// e.params.at(0) is receiver (us?)
|
||||||
auto to = _ircccm.getU(e.params.at(0)); // aka ContactTo
|
auto to = _ircccm.getU(e.params.at(0)); // aka ContactTo
|
||||||
if (!to.valid()) {
|
if (!to.valid()) {
|
||||||
std::cerr << "IRCCMM error: channel event unknown channel\n";
|
std::cerr << "IRCCMM error: privmsg event unknown channel\n";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: move this to contact
|
||||||
// upgrade contact to big
|
// upgrade contact to big
|
||||||
from.emplace_or_replace<Contact::Components::TagBig>(); // could be like an invite?
|
from.emplace_or_replace<Contact::Components::TagBig>(); // could be like an invite?
|
||||||
|
from.emplace_or_replace<Contact::Components::TagPrivate>();
|
||||||
|
|
||||||
return processMessage(from, to, e.params.at(1), false);
|
return processMessage(from, to, e.params.at(1), false);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user