2010-05-07 04:47:10 -05:00
|
|
|
/*
|
2011-12-03 16:38:03 -06:00
|
|
|
* Copyright 2009-2011, Andrea Anzani. All rights reserved.
|
2021-08-16 11:58:27 -05:00
|
|
|
* Copyright 2021, Jaidyn Levesque. All rights reserved.
|
2010-05-07 04:47:10 -05:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Andrea Anzani, andrea.anzani@gmail.com
|
2021-08-16 11:58:27 -05:00
|
|
|
* Jaidyn Levesque, jadedctrl@teknik.io
|
2010-05-07 04:47:10 -05:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <image.h>
|
|
|
|
|
2021-08-05 20:43:08 -05:00
|
|
|
#include <Bitmap.h>
|
2010-05-16 16:02:50 -05:00
|
|
|
#include <Directory.h>
|
|
|
|
#include <Entry.h>
|
|
|
|
#include <Handler.h>
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
#include "Account.h"
|
2021-08-05 20:43:08 -05:00
|
|
|
#include "AppMessages.h"
|
2021-08-16 11:58:27 -05:00
|
|
|
#include "ChatProtocolMessages.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
#include "ProtocolManager.h"
|
2021-08-16 11:58:27 -05:00
|
|
|
#include "ProtocolSettings.h"
|
2021-06-20 12:44:20 -05:00
|
|
|
#include "ChatProtocol.h"
|
2010-05-16 16:02:50 -05:00
|
|
|
#include "MainWindow.h"
|
|
|
|
#include "Server.h"
|
|
|
|
#include "TheApp.h"
|
2021-06-20 12:44:20 -05:00
|
|
|
#include "Utils.h"
|
2010-05-07 04:47:10 -05:00
|
|
|
|
|
|
|
static ProtocolManager* fInstance = NULL;
|
|
|
|
|
|
|
|
|
2021-08-15 00:53:45 -05:00
|
|
|
bool
|
2010-05-16 16:02:50 -05:00
|
|
|
ProtocolManager::Init(BDirectory dir, BHandler* target)
|
2010-05-07 04:47:10 -05:00
|
|
|
{
|
|
|
|
BEntry entry;
|
|
|
|
BPath path;
|
2021-08-15 00:53:45 -05:00
|
|
|
bool ret = false;
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
dir.Rewind();
|
2010-05-07 04:47:10 -05:00
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
while (dir.GetNextEntry(&entry) == B_OK) {
|
2010-05-07 04:47:10 -05:00
|
|
|
path = BPath(&entry);
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
// Load protocol addon
|
2010-05-07 04:47:10 -05:00
|
|
|
image_id id = load_add_on(path.Path());
|
2010-05-16 16:02:50 -05:00
|
|
|
if (id < 0)
|
|
|
|
continue;
|
|
|
|
|
2022-02-23 12:11:17 -06:00
|
|
|
// Refuse to load add-on under some circumstances…
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocolAddOn* addOn = new ChatProtocolAddOn(id, path.Path());
|
2022-02-23 12:11:17 -06:00
|
|
|
if (addOn->Version() != APP_VERSION || ProtocolAddOn(addOn->Signature()) != NULL) {
|
|
|
|
if (addOn->Version() != APP_VERSION)
|
|
|
|
printf("%s not loaded, due to insufficient version (%i v %i).\n",
|
|
|
|
addOn->Signature(), addOn->Version(), APP_VERSION);
|
|
|
|
else if (ProtocolAddOn(addOn->Signature()) != NULL)
|
|
|
|
printf("%s not loaded, due to another instance already having been loaded.\n",
|
|
|
|
addOn->Signature());
|
|
|
|
delete addOn;
|
Allow multiple protocols per add-on
Now an add-on can contain multiple protocols, and the protocol API has
changed. An add-on must now export protocol_count() and protocol_at(),
with the latter replacing protocol(). protocol_count() returning the
amount of protocols in a given add-on, and protocol_at(i) giving a
new CayaProtocol* "at" the given index.
CayaProtocol has also been changed, adding Signature(),
FriendlySignature(), Icon(), Path(), and SetPath(). The reasoning is
that different protocols (even within a single add-on) will have
different signatures and icons, so this data should be accessible from
the protocol itself.
CayaProtocolAddOn now has CountProtocols() and ProtocolAt(i), allowing
the accessing of multiple protocols. A CayaProtocolAddOn can be given a
default protocol index in the constructor, whose protocol will be
returned with Protocol(). Version() was also moved from CayaProtocol to
CayaProtocolAddOn.
2021-05-21 13:33:43 -05:00
|
|
|
continue;
|
2022-02-23 12:11:17 -06:00
|
|
|
}
|
2021-08-15 00:53:45 -05:00
|
|
|
ret = true;
|
Allow multiple protocols per add-on
Now an add-on can contain multiple protocols, and the protocol API has
changed. An add-on must now export protocol_count() and protocol_at(),
with the latter replacing protocol(). protocol_count() returning the
amount of protocols in a given add-on, and protocol_at(i) giving a
new CayaProtocol* "at" the given index.
CayaProtocol has also been changed, adding Signature(),
FriendlySignature(), Icon(), Path(), and SetPath(). The reasoning is
that different protocols (even within a single add-on) will have
different signatures and icons, so this data should be accessible from
the protocol itself.
CayaProtocolAddOn now has CountProtocols() and ProtocolAt(i), allowing
the accessing of multiple protocols. A CayaProtocolAddOn can be given a
default protocol index in the constructor, whose protocol will be
returned with Protocol(). Version() was also moved from CayaProtocol to
CayaProtocolAddOn.
2021-05-21 13:33:43 -05:00
|
|
|
|
|
|
|
// If add-on has multiple protocols, also load them
|
2021-06-11 21:43:50 -05:00
|
|
|
for (int32 i = 0; i < addOn->CountProtocols(); i++) {
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocolAddOn* subAddOn = addOn;
|
2021-06-11 21:43:50 -05:00
|
|
|
if (i > 0)
|
2021-06-20 12:44:20 -05:00
|
|
|
subAddOn = new ChatProtocolAddOn(id, path.Path(), i);
|
2021-06-11 21:43:50 -05:00
|
|
|
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocol* proto = subAddOn->Protocol();
|
Allow multiple protocols per add-on
Now an add-on can contain multiple protocols, and the protocol API has
changed. An add-on must now export protocol_count() and protocol_at(),
with the latter replacing protocol(). protocol_count() returning the
amount of protocols in a given add-on, and protocol_at(i) giving a
new CayaProtocol* "at" the given index.
CayaProtocol has also been changed, adding Signature(),
FriendlySignature(), Icon(), Path(), and SetPath(). The reasoning is
that different protocols (even within a single add-on) will have
different signatures and icons, so this data should be accessible from
the protocol itself.
CayaProtocolAddOn now has CountProtocols() and ProtocolAt(i), allowing
the accessing of multiple protocols. A CayaProtocolAddOn can be given a
default protocol index in the constructor, whose protocol will be
returned with Protocol(). Version() was also moved from CayaProtocol to
CayaProtocolAddOn.
2021-05-21 13:33:43 -05:00
|
|
|
|
|
|
|
fAddOnMap.AddItem(proto->Signature(), subAddOn);
|
2021-06-11 21:43:50 -05:00
|
|
|
_LoadAccounts(path.Path(), subAddOn, i, target);
|
Allow multiple protocols per add-on
Now an add-on can contain multiple protocols, and the protocol API has
changed. An add-on must now export protocol_count() and protocol_at(),
with the latter replacing protocol(). protocol_count() returning the
amount of protocols in a given add-on, and protocol_at(i) giving a
new CayaProtocol* "at" the given index.
CayaProtocol has also been changed, adding Signature(),
FriendlySignature(), Icon(), Path(), and SetPath(). The reasoning is
that different protocols (even within a single add-on) will have
different signatures and icons, so this data should be accessible from
the protocol itself.
CayaProtocolAddOn now has CountProtocols() and ProtocolAt(i), allowing
the accessing of multiple protocols. A CayaProtocolAddOn can be given a
default protocol index in the constructor, whose protocol will be
returned with Protocol(). Version() was also moved from CayaProtocol to
CayaProtocolAddOn.
2021-05-21 13:33:43 -05:00
|
|
|
delete proto;
|
2010-07-10 14:28:29 -05:00
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
2021-08-15 00:53:45 -05:00
|
|
|
return ret;
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolManager::ProtocolManager()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ProtocolManager*
|
|
|
|
ProtocolManager::Get()
|
|
|
|
{
|
|
|
|
if (fInstance == NULL)
|
|
|
|
fInstance = new ProtocolManager();
|
|
|
|
return fInstance;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-28 12:11:16 -05:00
|
|
|
uint32
|
|
|
|
ProtocolManager::CountProtocolAddOns() const
|
2010-05-16 16:02:50 -05:00
|
|
|
{
|
2010-05-28 12:11:16 -05:00
|
|
|
return fAddOnMap.CountItems();
|
2010-05-16 16:02:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocolAddOn*
|
2010-05-28 12:11:16 -05:00
|
|
|
ProtocolManager::ProtocolAddOnAt(uint32 i) const
|
2010-05-16 16:02:50 -05:00
|
|
|
{
|
2010-05-28 12:11:16 -05:00
|
|
|
return fAddOnMap.ValueAt(i);
|
2010-05-16 16:02:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocolAddOn*
|
2010-05-28 12:11:16 -05:00
|
|
|
ProtocolManager::ProtocolAddOn(const char* signature)
|
2010-05-07 04:47:10 -05:00
|
|
|
{
|
2010-05-28 12:11:16 -05:00
|
|
|
return fAddOnMap.ValueFor(signature);
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-28 12:11:16 -05:00
|
|
|
uint32
|
|
|
|
ProtocolManager::CountProtocolInstances() const
|
2010-05-07 04:47:10 -05:00
|
|
|
{
|
2010-05-28 12:11:16 -05:00
|
|
|
return fProtocolMap.CountItems();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocol*
|
2010-05-28 12:11:16 -05:00
|
|
|
ProtocolManager::ProtocolInstanceAt(uint32 i) const
|
|
|
|
{
|
|
|
|
return fProtocolMap.ValueAt(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocol*
|
2010-05-28 12:11:16 -05:00
|
|
|
ProtocolManager::ProtocolInstance(bigtime_t identifier)
|
|
|
|
{
|
|
|
|
return fProtocolMap.ValueFor(identifier);
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
void
|
2021-06-20 12:44:20 -05:00
|
|
|
ProtocolManager::AddAccount(ChatProtocolAddOn* addOn, const char* account,
|
2021-08-16 11:58:27 -05:00
|
|
|
BHandler* target)
|
2010-05-07 04:47:10 -05:00
|
|
|
{
|
2021-08-16 11:58:27 -05:00
|
|
|
// If already active, don't double-dip!
|
|
|
|
bool active = false;
|
2022-02-23 15:42:46 -06:00
|
|
|
Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
2021-08-16 11:58:27 -05:00
|
|
|
if (active == true)
|
|
|
|
return;
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
bigtime_t instanceId = system_time();
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocol* cayap = addOn->Protocol();
|
2021-08-05 20:43:08 -05:00
|
|
|
Account* acc =
|
|
|
|
new Account(instanceId, cayap, account, addOn->Signature(), target);
|
|
|
|
|
2021-08-16 11:58:27 -05:00
|
|
|
// If account is disabled, just let it go
|
|
|
|
if (acc->InitCheck() == B_DONT_DO_THAT) {
|
|
|
|
delete acc;
|
|
|
|
return;
|
|
|
|
}
|
2021-08-05 20:43:08 -05:00
|
|
|
// Send a "whoops" notification if hits a failure
|
2021-08-16 11:58:27 -05:00
|
|
|
else if (acc->InitCheck() != B_OK) {
|
2021-08-05 20:43:08 -05:00
|
|
|
BMessage error(APP_ACCOUNT_FAILED);
|
|
|
|
cayap->Icon()->Archive(&error);
|
|
|
|
error.AddString("name", account);
|
2021-08-16 11:58:27 -05:00
|
|
|
_MainWin()->MessageReceived(&error);
|
2021-08-05 20:43:08 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
fProtocolMap.AddItem(instanceId, cayap);
|
|
|
|
|
2022-02-23 15:42:46 -06:00
|
|
|
Server::Get()->AddProtocolLooper(instanceId, cayap);
|
2021-08-16 11:58:27 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ProtocolManager::EnableAccount(ProtocolSettings* settings, const char* account)
|
|
|
|
{
|
|
|
|
BMessage* msg = NULL;
|
|
|
|
if (settings->Load(account, &msg) == B_OK) {
|
|
|
|
if (msg->HasBool("disabled"))
|
|
|
|
msg->ReplaceBool("disabled", false);
|
|
|
|
else
|
|
|
|
msg->AddBool("disabled", false);
|
|
|
|
settings->Save(account, *msg);
|
|
|
|
}
|
|
|
|
AddAccount(settings->AddOn(), account, _MainWin());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ProtocolManager::DisableAccount(ProtocolSettings* settings, const char* account)
|
|
|
|
{
|
|
|
|
bool active = false;
|
|
|
|
int64 instance
|
2022-02-23 15:42:46 -06:00
|
|
|
= Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
2021-08-16 11:58:27 -05:00
|
|
|
if (active == false)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BMessage* msg = NULL;
|
|
|
|
if (settings->Load(account, &msg) == B_OK) {
|
|
|
|
if (msg->HasBool("disabled"))
|
|
|
|
msg->ReplaceBool("disabled", true);
|
|
|
|
else
|
|
|
|
msg->AddBool("disabled", true);
|
|
|
|
settings->Save(account, *msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
BMessage remove(IM_MESSAGE);
|
|
|
|
remove.AddInt32("im_what", IM_PROTOCOL_DISABLE);
|
|
|
|
remove.AddInt64("instance", instance);
|
|
|
|
_MainWin()->PostMessage(&remove);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ProtocolManager::ToggleAccount(ProtocolSettings* settings, const char* account)
|
|
|
|
{
|
|
|
|
bool active = false;
|
|
|
|
int64 instance
|
2022-02-23 15:42:46 -06:00
|
|
|
= Server::Get()->GetActiveAccounts().ValueFor(BString(account), &active);
|
2021-08-16 11:58:27 -05:00
|
|
|
|
|
|
|
if (active == true)
|
|
|
|
DisableAccount(settings, account);
|
|
|
|
else
|
|
|
|
EnableAccount(settings, account);
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-16 16:02:50 -05:00
|
|
|
void
|
2021-06-20 12:44:20 -05:00
|
|
|
ProtocolManager::_LoadAccounts(const char* image_path, ChatProtocolAddOn* addOn,
|
2021-08-16 11:58:27 -05:00
|
|
|
int protoIndex, BHandler* target)
|
2010-05-07 04:47:10 -05:00
|
|
|
{
|
2010-05-16 16:02:50 -05:00
|
|
|
// Find accounts path for this protocol
|
2021-06-20 12:44:20 -05:00
|
|
|
BPath path(AccountPath(addOn->Signature(), addOn->Protocol()->Signature()));
|
2010-05-16 16:02:50 -05:00
|
|
|
if (path.InitCheck() != B_OK)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BDirectory dir(path.Path());
|
|
|
|
BEntry entry;
|
2021-06-11 21:43:50 -05:00
|
|
|
bool firstDone = false;
|
|
|
|
|
2021-08-15 00:53:45 -05:00
|
|
|
while (dir.GetNextEntry(&entry) == B_OK)
|
|
|
|
_LoadAccount(addOn, entry, target);
|
2021-06-11 21:43:50 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
ProtocolManager::_LoadAccount(const char* imagePath, BEntry accountEntry,
|
2021-08-16 11:58:27 -05:00
|
|
|
int protoIndex, BHandler* target)
|
2021-06-11 21:43:50 -05:00
|
|
|
{
|
|
|
|
image_id id = load_add_on(imagePath);
|
|
|
|
if (id < 0)
|
|
|
|
return;
|
|
|
|
|
2021-08-16 11:58:27 -05:00
|
|
|
// If add-on's API version fits then load accounts…
|
2021-06-20 12:44:20 -05:00
|
|
|
ChatProtocolAddOn* addOn = new ChatProtocolAddOn(id, imagePath, protoIndex);
|
|
|
|
if (addOn->Version() != APP_VERSION)
|
2021-06-11 21:43:50 -05:00
|
|
|
return;
|
|
|
|
|
|
|
|
_LoadAccount(addOn, accountEntry, target);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
2021-06-20 12:44:20 -05:00
|
|
|
ProtocolManager::_LoadAccount(ChatProtocolAddOn* addOn, BEntry accountEntry,
|
2021-08-16 11:58:27 -05:00
|
|
|
BHandler* target)
|
2021-06-11 21:43:50 -05:00
|
|
|
{
|
|
|
|
BFile file(&accountEntry, B_READ_ONLY);
|
|
|
|
BMessage msg;
|
|
|
|
|
|
|
|
if (msg.Unflatten(&file) == B_OK) {
|
|
|
|
char buffer[B_PATH_NAME_LENGTH];
|
|
|
|
if (accountEntry.GetName(buffer) == B_OK) {
|
|
|
|
printf("Found %s for protocol %s!\n", buffer, addOn->Protocol()->Signature());
|
|
|
|
AddAccount(addOn, buffer, target);
|
2010-05-16 16:02:50 -05:00
|
|
|
}
|
|
|
|
}
|
2010-05-07 04:47:10 -05:00
|
|
|
}
|
2021-08-16 11:58:27 -05:00
|
|
|
|
|
|
|
|
|
|
|
MainWindow*
|
|
|
|
ProtocolManager::_MainWin()
|
|
|
|
{
|
|
|
|
return ((TheApp*)be_app)->GetMainWindow();
|
|
|
|
}
|