Basic IRC connection/messaging/joining, etc.

This commit is contained in:
Jaidyn Ann 2021-06-21 01:54:42 -05:00
parent 57ecbd1cb3
commit 0c615b01fd
2 changed files with 247 additions and 9 deletions

View File

@ -7,11 +7,21 @@
#include <iostream> #include <iostream>
#include <StringList.h>
#include <ChatProtocolMessages.h>
IrcProtocol* current_proto;
status_t status_t
connect_thread(void* data) connect_thread(void* data)
{ {
BMessage* settings = (BMessage*)data; IrcProtocol* proto = (IrcProtocol*)data;
current_proto = proto;
BMessage* settings = proto->fSettings;
if (!settings) if (!settings)
return B_ERROR; return B_ERROR;
@ -32,11 +42,14 @@ connect_thread(void* data)
joinServer << "#"; joinServer << "#";
joinServer << server; joinServer << server;
settings->PrintToStream();
// Now create the session // Now create the session
irc_callbacks_t callbacks = get_callbacks(); irc_callbacks_t callbacks = get_callbacks();
irc_session_t* session = irc_create_session(&callbacks); irc_session_t* session = irc_create_session(&callbacks);
proto->fSession = session;
irc_ctx_t ctx;
ctx.nick.SetTo(nick);
irc_set_ctx(session, &ctx);
if (!session) if (!session)
return B_ERROR; return B_ERROR;
@ -82,6 +95,61 @@ IrcProtocol::Shutdown()
status_t status_t
IrcProtocol::Process(BMessage* msg) IrcProtocol::Process(BMessage* msg)
{ {
BString chat_id;
if (msg->FindString("chat_id", &chat_id) != B_OK)
return B_ERROR;
switch (msg->FindInt32("im_what"))
{
case IM_SEND_MESSAGE:
{
BString body;
if (msg->FindString("body", &body) != B_OK)
return B_ERROR;
irc_cmd_msg(fSession, chat_id.String(), body.String());
irc_ctx_t* ctx = (irc_ctx_t*)irc_get_ctx(fSession);
BMessage sendMsg(*msg);
sendMsg.ReplaceInt32("im_what", IM_MESSAGE_SENT);
sendMsg.AddString("user_id", ctx->id);
_SendMessage(&sendMsg);
break;
}
case IM_JOIN_ROOM:
case IM_CREATE_ROOM:
{
irc_cmd_join(fSession, chat_id.String(), "");
break;
}
case IM_LEAVE_ROOM:
{
irc_cmd_part(fSession, chat_id.String());
break;
}
case IM_GET_ROOM_PARTICIPANTS:
{
irc_cmd_names(fSession, chat_id.String());
break;
}
case IM_ROOM_SEND_INVITE:
{
BString user_id;
if (msg->FindString("user_id", &user_id) != B_OK)
return B_ERROR;
irc_cmd_invite(fSession, user_id.String(), chat_id.String());
break;
}
case IM_ROOM_KICK_PARTICIPANT:
{
BString user_id;
if (msg->FindString("user_id", &user_id) != B_OK)
return B_ERROR;
irc_cmd_kick(fSession, user_id.String(), chat_id.String(),
msg->FindString("body"));
break;
}
}
return B_OK; return B_OK;
} }
@ -89,8 +157,9 @@ IrcProtocol::Process(BMessage* msg)
status_t status_t
IrcProtocol::UpdateSettings(BMessage* msg) IrcProtocol::UpdateSettings(BMessage* msg)
{ {
fSettings = msg;
fServerThread = spawn_thread(connect_thread, "connect_thread", fServerThread = spawn_thread(connect_thread, "connect_thread",
B_NORMAL_PRIORITY, (void*)msg); B_NORMAL_PRIORITY, (void*)this);
if (fServerThread < B_OK) if (fServerThread < B_OK)
return B_ERROR; return B_ERROR;
@ -211,6 +280,10 @@ get_callbacks()
callbacks.event_connect = event_connect; callbacks.event_connect = event_connect;
callbacks.event_numeric = event_numeric; callbacks.event_numeric = event_numeric;
callbacks.event_join = event_join; callbacks.event_join = event_join;
callbacks.event_part = event_part;
callbacks.event_channel = event_channel;
callbacks.event_privmsg = event_privmsg;
callbacks.event_nick = event_nick;
return callbacks; return callbacks;
} }
@ -219,18 +292,157 @@ void
event_connect(irc_session_t* session, const char* event, event_connect(irc_session_t* session, const char* event,
const char* origin, const char** params, unsigned int count) const char* origin, const char** params, unsigned int count)
{ {
BMessage readyMsg(IM_MESSAGE);
readyMsg.AddInt32("im_what", IM_PROTOCOL_READY);
_SendMessage(&readyMsg);
} }
void void
event_numeric(irc_session_t* session, unsigned int blah, event_numeric(irc_session_t* session, unsigned int event,
const char* origin, const char** params, unsigned int count) const char* origin, const char** params, unsigned int count)
{ {
switch (event) {
case LIBIRC_RFC_RPL_NAMREPLY:
{
BStringList user_id;
BStringList user_name;
BString user_list(params[3]);
user_list.Split(" ", false, user_id);
BMessage list(IM_MESSAGE);
list.AddInt32("im_what", IM_ROOM_PARTICIPANTS);
list.AddString("chat_id", params[2]);
list.AddStrings("user_id", user_id);
list.AddStrings("user_name", user_id);
_SendMessage(&list);
break;
}
}
} }
void void
event_join(irc_session_t* session, const char* event, const char* origin, event_join(irc_session_t* session, const char* event, const char* joiner,
const char** params, unsigned int count) const char** channel, unsigned int count)
{ {
int32 im_what = IM_ROOM_PARTICIPANT_JOINED;
irc_ctx_t* ctx = (irc_ctx_t*)irc_get_ctx(session);
if (_IsOwnUser(joiner, session) == true)
im_what = IM_ROOM_JOINED;
BMessage joinedMsg(IM_MESSAGE);
joinedMsg.AddInt32("im_what", im_what);
joinedMsg.AddString("user_id", joiner);
joinedMsg.AddString("chat_id", channel[0]);
_SendMessage(&joinedMsg);
}
void
event_part(irc_session_t* session, const char* event, const char* quitter,
const char** chanReason, unsigned int count)
{
int32 im_what = IM_ROOM_PARTICIPANT_LEFT;
if (_IsOwnUser(quitter, session) == true)
im_what = IM_ROOM_LEFT;
BString body;
if (chanReason[1] != NULL)
body << chanReason[1];
BMessage quitMsg(IM_MESSAGE);
quitMsg.AddInt32("im_what", im_what);
quitMsg.AddString("user_id", quitter);
quitMsg.AddString("chat_id", chanReason[0]);
if (body.IsEmpty() == false)
quitMsg.AddString("body", body);
_SendMessage(&quitMsg);
}
void
event_channel(irc_session_t* session, const char* event, const char* sender,
const char** chanBody, unsigned int count)
{
BMessage msgMsg(IM_MESSAGE);
msgMsg.AddInt32("im_what", IM_MESSAGE_RECEIVED);
msgMsg.AddString("user_id", sender);
msgMsg.AddString("chat_id", chanBody[0]);
msgMsg.AddString("body", chanBody[1]);
_SendMessage(&msgMsg);
}
void
event_privmsg(irc_session_t* session, const char* event, const char* sender,
const char** selfBody, unsigned int count)
{
BMessage msgMsg(IM_MESSAGE);
msgMsg.AddInt32("im_what", IM_MESSAGE_RECEIVED);
msgMsg.AddString("user_id", sender);
msgMsg.AddString("chat_id", _UserNick(sender));
msgMsg.AddString("body", selfBody[1]);
_SendMessage(&msgMsg);
}
// TODO: Nick-change API
void
event_nick(irc_session_t* session, const char* event, const char* oldNick,
const char** newNick, unsigned int count)
{
irc_ctx_t* ctx = (irc_ctx_t*)irc_get_ctx(session);
if (_IsOwnUser(oldNick, session) == true) {
ctx->nick.SetTo(newNick[0]);
irc_set_ctx(session, ctx);
}
}
BString
_UserNick(const char* userId)
{
BStringList split;
BString id(userId);
id.Split("!", false, split);
return split.StringAt(0);
}
bool
_IsOwnUser(const char* userId, irc_session_t* session)
{
bool ret = false;
irc_ctx_t* ctx = (irc_ctx_t*)irc_get_ctx(session);
if (ctx->nick == _UserNick(userId)) {
ret = true;
if (ctx->id.IsEmpty() == true) {
ctx->id.SetTo(userId);
irc_set_ctx(session, ctx);
// The app hasn't been informed of user_id, then!
BMessage ownInfo(IM_MESSAGE);
ownInfo.AddInt32("im_what", IM_OWN_CONTACT_INFO);
ownInfo.AddString("user_id", userId);
ownInfo.AddString("user_name", ctx->nick);
_SendMessage(&ownInfo);
}
}
return ret;
}
void
_SendMessage(BMessage* msg)
{
if (!msg)
return;
msg->AddString("protocol", current_proto->Signature());
current_proto->MessengerInterface()->SendMessage(msg);
} }

View File

@ -18,6 +18,14 @@
status_t connect_thread(void* data); status_t connect_thread(void* data);
typedef struct
{
BString nick;
BString id;
} irc_ctx_t;
class IrcProtocol : public ChatProtocol { class IrcProtocol : public ChatProtocol {
public: public:
IrcProtocol(); IrcProtocol();
@ -51,6 +59,9 @@ public:
virtual ChatProtocolMessengerInterface* virtual ChatProtocolMessengerInterface*
MessengerInterface() const; MessengerInterface() const;
// IRC
BMessage* fSettings;
irc_session_t* fSession;
private: private:
ChatProtocolMessengerInterface* fMessenger; ChatProtocolMessengerInterface* fMessenger;
@ -69,11 +80,26 @@ void event_connect(irc_session_t* session, const char* event,
const char* origin, const char** params, const char* origin, const char** params,
unsigned int count); unsigned int count);
void event_numeric(irc_session_t* session, unsigned int blah, void event_numeric(irc_session_t* session, unsigned int event,
const char* origin, const char** params, unsigned int count); const char* origin, const char** params, unsigned int count);
void event_join(irc_session_t* session, const char* event, void event_join(irc_session_t* session, const char* event,
const char* origin, const char** params, unsigned int count); const char* joiner, const char** channel, unsigned int count);
void event_part(irc_session_t* session, const char* event,
const char* quitter, const char** chanReason, unsigned int count);
void event_channel(irc_session_t* session, const char* event,
const char* sender, const char** chanBody, unsigned int count);
void event_privmsg(irc_session_t* session, const char* event,
const char* sender, const char** selfBody, unsigned int count);
void event_nick(irc_session_t* session, const char* event,
const char* oldNick, const char** newNick, unsigned int count);
BString _UserNick(const char* userId);
bool _IsOwnUser(const char* userId, irc_session_t* session);
void _SendMessage(BMessage* msg);
#endif // _IRC_PROTOCOL_H #endif // _IRC_PROTOCOL_H