added basic browser extension stuff

This commit is contained in:
fourtf 2018-04-09 22:59:19 +02:00
parent 5fb42af9d0
commit 2687da38ba
19 changed files with 367 additions and 228 deletions

19
browser_ext/.editorconfig Normal file
View file

@ -0,0 +1,19 @@
root = true
[*]
# Change these settings to your own preference
indent_style = space
indent_size = 2
# We recommend you to keep these unchanged
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false
[Makefile]
indent_style = tab

66
browser_ext/background.js Normal file
View file

@ -0,0 +1,66 @@
const ignoredPages = {
"settings": true,
"payments": true,
"inventory": true,
"messages": true,
"subscriptions": true,
"friends": true,
"directory": true,
};
const appName = "com.chatterino.chatterino";
function matchUrl(url) {
if (!url)
return;
const match = url.match(/^https?:\/\/(www\.)?twitch.tv\/([a-zA-Z0-9]+)\/?$/);
if (match) {
const channelName = match[2];
if (!ignoredPages[channelName]) {
selectChannel(channelName);
}
}
}
var port = chrome.runtime.connectNative("com.chatterino.chatterino");
port.onMessage.addListener(function(msg) {
console.log(msg);
});
port.onDisconnect.addListener(function() {
console.log("Disconnected");
});
port.postMessage({ text: "Hello, my_application" });
function selectChannel(channelName) {
console.log(channelName);
port.postMessage({channelName: channelName});
// chrome.runtime.sendNativeMessage(appName, { "xd": true }, (resp) => {
// console.log(resp);
// })
}
/// add listeners
chrome.tabs.onActivated.addListener((activeInfo) => {
chrome.tabs.get(activeInfo.tabId, (tab) => {
if (!tab)
return;
if (!tab.url)
return;
matchUrl(tab.url);
});
});
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (!tab.highlighted)
return;
matchUrl(changeInfo.url);
});

BIN
browser_ext/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

21
browser_ext/manifest.json Normal file
View file

@ -0,0 +1,21 @@
{
"name": "Chatterino",
"version": "1.0",
"description": "xd",
"permissions": [
"tabs", "nativeMessaging"
],
"icons": {
"256": "icon.png"
},
"manifest_version": 2,
"background": {
"scripts": [
"background.js"
],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html"
}
}

6
browser_ext/popup.html Normal file
View file

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
xd
</body>
</html>

View file

@ -103,7 +103,6 @@ SOURCES += \
src/providers/twitch/twitchmessagebuilder.cpp \ src/providers/twitch/twitchmessagebuilder.cpp \
src/providers/twitch/twitchserver.cpp \ src/providers/twitch/twitchserver.cpp \
src/singletons/accountmanager.cpp \ src/singletons/accountmanager.cpp \
src/singletons/channelmanager.cpp \
src/singletons/commandmanager.cpp \ src/singletons/commandmanager.cpp \
src/singletons/emotemanager.cpp \ src/singletons/emotemanager.cpp \
src/singletons/fontmanager.cpp \ src/singletons/fontmanager.cpp \
@ -171,7 +170,8 @@ SOURCES += \
src/providers/twitch/twitchhelpers.cpp \ src/providers/twitch/twitchhelpers.cpp \
src/widgets/helper/signallabel.cpp \ src/widgets/helper/signallabel.cpp \
src/widgets/helper/debugpopup.cpp \ src/widgets/helper/debugpopup.cpp \
src/util/debugcount.cpp src/util/debugcount.cpp \
src/singletons/nativemessagingmanager.cpp
HEADERS += \ HEADERS += \
src/precompiled_header.hpp \ src/precompiled_header.hpp \
@ -201,7 +201,6 @@ HEADERS += \
src/providers/twitch/twitchmessagebuilder.hpp \ src/providers/twitch/twitchmessagebuilder.hpp \
src/providers/twitch/twitchserver.hpp \ src/providers/twitch/twitchserver.hpp \
src/singletons/accountmanager.hpp \ src/singletons/accountmanager.hpp \
src/singletons/channelmanager.hpp \
src/singletons/commandmanager.hpp \ src/singletons/commandmanager.hpp \
src/singletons/emotemanager.hpp \ src/singletons/emotemanager.hpp \
src/singletons/fontmanager.hpp \ src/singletons/fontmanager.hpp \
@ -212,7 +211,6 @@ HEADERS += \
src/singletons/loggingmanager.hpp \ src/singletons/loggingmanager.hpp \
src/singletons/pathmanager.hpp \ src/singletons/pathmanager.hpp \
src/singletons/resourcemanager.hpp \ src/singletons/resourcemanager.hpp \
src/singletons/settingsmanager.hpp \
src/singletons/thememanager.hpp \ src/singletons/thememanager.hpp \
src/singletons/windowmanager.hpp \ src/singletons/windowmanager.hpp \
src/util/benchmark.hpp \ src/util/benchmark.hpp \
@ -288,7 +286,9 @@ HEADERS += \
src/providers/twitch/twitchhelpers.hpp \ src/providers/twitch/twitchhelpers.hpp \
src/util/debugcount.hpp \ src/util/debugcount.hpp \
src/widgets/helper/debugpopup.hpp \ src/widgets/helper/debugpopup.hpp \
src/version.hpp src/version.hpp \
src/singletons/settingsmanager.hpp \
src/singletons/nativemessagingmanager.hpp
RESOURCES += \ RESOURCES += \
resources/resources.qrc resources/resources.qrc

View file

@ -4,6 +4,7 @@
#include "singletons/commandmanager.hpp" #include "singletons/commandmanager.hpp"
#include "singletons/emotemanager.hpp" #include "singletons/emotemanager.hpp"
#include "singletons/loggingmanager.hpp" #include "singletons/loggingmanager.hpp"
#include "singletons/nativemessagingmanager.hpp"
#include "singletons/settingsmanager.hpp" #include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp" #include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp" #include "singletons/windowmanager.hpp"
@ -17,6 +18,8 @@ namespace chatterino {
Application::Application() Application::Application()
{ {
singletons::NativeMessagingManager::getInstance().registerHost();
singletons::WindowManager::getInstance(); singletons::WindowManager::getInstance();
singletons::LoggingManager::getInstance(); singletons::LoggingManager::getInstance();

View file

@ -3,7 +3,11 @@
#include <QAbstractNativeEventFilter> #include <QAbstractNativeEventFilter>
#include <QApplication> #include <QApplication>
#include <QFile>
#include <QLibrary> #include <QLibrary>
#include <QStringList>
#include <iostream>
#include "util/networkmanager.hpp" #include "util/networkmanager.hpp"
@ -11,7 +15,37 @@
#include "util/nativeeventhelper.hpp" #include "util/nativeeventhelper.hpp"
#endif #endif
#include "fstream"
#ifdef Q_OS_WIN
#include "fcntl.h"
#include "io.h"
#include "stdio.h"
#endif
void runNativeMessagingHost();
int runGui(int argc, char *argv[]);
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{
// read args
QStringList args;
for (int i = 1; i < argc; i++) {
args << argv[i];
}
// TODO: can be any argument
if (args.size() > 0 && args[0].startsWith("chrome-extension://")) {
runNativeMessagingHost();
return 0;
}
// run gui
return runGui(argc, argv);
}
int runGui(int argc, char *argv[])
{ {
QApplication::setAttribute(Qt::AA_Use96Dpi, true); QApplication::setAttribute(Qt::AA_Use96Dpi, true);
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
@ -55,3 +89,44 @@ int main(int argc, char *argv[])
_exit(0); _exit(0);
} }
void writeByteArray(QByteArray a)
{
char *data = a.data();
uint32_t size;
size = a.size();
std::cout.write(reinterpret_cast<char *>(&size), 4);
std::cout.write(data, a.size());
}
void runNativeMessagingHost()
{
#ifdef Q_OS_WIN
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
#endif
// std::ofstream xd("C:\\users\\daniel\\desktop\\xd.lmao");
while (true) {
char size_c[4];
std::cin.read(size_c, 4);
if (std::cin.eof()) {
break;
}
uint32_t size = *reinterpret_cast<uint32_t *>(size_c);
char *b = (char *)malloc(size + 1);
std::cin.read(b, size);
*(b + size) = '\0';
// xd << b;
// xd.flush();
free(b);
// writeByteArray(QString("{\"xd\":1}").toUtf8());
}
}

View file

@ -3,7 +3,6 @@
#include "debug/log.hpp" #include "debug/log.hpp"
#include "messages/message.hpp" #include "messages/message.hpp"
#include "providers/twitch/twitchmessagebuilder.hpp" #include "providers/twitch/twitchmessagebuilder.hpp"
#include "singletons/channelmanager.hpp"
#include "singletons/emotemanager.hpp" #include "singletons/emotemanager.hpp"
#include "singletons/ircmanager.hpp" #include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp" #include "singletons/settingsmanager.hpp"

View file

@ -1,149 +0,0 @@
//#include "singletons/channelmanager.hpp"
//#include "singletons/ircmanager.hpp"
// namespace chatterino {
// namespace singletons {
// ChannelManager &ChannelManager::getInstance()
//{
// static ChannelManager instance;
// return instance;
//}
// ChannelManager::ChannelManager()
// : whispersChannel(new Channel("/whispers"))
// , mentionsChannel(new Channel("/mentions"))
// , emptyChannel(new Channel(""))
//{
//}
// const std::vector<ChannelPtr> ChannelManager::getItems()
//{
// QMutexLocker locker(&this->channelsMutex);
// std::vector<ChannelPtr> items;
// for (auto &item : this->twitchChannels.values()) {
// items.push_back(std::get<0>(item));
// }
// return items;
//}
// ChannelPtr ChannelManager::addTwitchChannel(const QString &rawChannelName)
//{
// QString channelName = rawChannelName.toLower();
// if (channelName.length() > 1 && channelName.at(0) == '/') {
// return this->getTwitchChannel(channelName);
// }
// if (channelName.length() > 0 && channelName.at(0) == '#') {
// channelName = channelName.mid(1);
// }
// QMutexLocker locker(&this->channelsMutex);
// auto it = this->twitchChannels.find(channelName);
// if (it == this->twitchChannels.end()) {
// auto channel = std::make_shared<TwitchChannel>(channelName);
// this->twitchChannels.insert(channelName, std::make_tuple(channel, 1));
// this->ircJoin.invoke(channelName);
// return channel;
// }
// std::get<1>(it.value())++;
// return std::get<0>(it.value());
//}
// ChannelPtr ChannelManager::getTwitchChannel(const QString &channel)
//{
// QMutexLocker locker(&this->channelsMutex);
// QString c = channel.toLower();
// if (channel.length() > 1 && channel.at(0) == '/') {
// if (c == "/whispers") {
// return whispersChannel;
// }
// if (c == "/mentions") {
// return mentionsChannel;
// }
// return emptyChannel;
// }
// auto a = this->twitchChannels.find(c);
// if (a == this->twitchChannels.end()) {
// return emptyChannel;
// }
// return std::get<0>(a.value());
//}
// void ChannelManager::removeTwitchChannel(const QString &channel)
//{
// QMutexLocker locker(&this->channelsMutex);
// if (channel.length() > 1 && channel.at(0) == '/') {
// return;
// }
// QString c = channel.toLower();
// auto a = this->twitchChannels.find(c);
// if (a == this->twitchChannels.end()) {
// return;
// }
// std::get<1>(a.value())--;
// if (std::get<1>(a.value()) == 0) {
// this->ircPart.invoke(c);
// this->twitchChannels.remove(c);
// }
//}
// const std::string &ChannelManager::getUserID(const std::string &username)
//{
// /* TODO: Implement
// auto it = this->usernameToID.find(username);
// if (it != std::end(this->usernameToID)) {
// return *it;
// }
// */
// static std::string temporary = "xd";
// return temporary;
//}
// void ChannelManager::doOnAll(std::function<void(ChannelPtr)> func)
//{
// for (const auto &channel : this->twitchChannels) {
// func(std::get<0>(channel));
// }
// func(this->whispersChannel);
// func(this->mentionsChannel);
//}
//}
// void ChannelManager::doOnAllNormalChannels(std::function<void(ChannelPtr)> func)
//{
// for (const auto &channel : this->twitchChannels) {
// func(std::get<0>(channel));
// }
//}
//} // namespace chatterino
//}

View file

@ -1,46 +0,0 @@
//#pragma once
//#include "channel.hpp"
//#include "channeldata.hpp"
//#include "providers/twitch/twitchchannel.hpp"
//#include <map>
// namespace chatterino {
// namespace singletons {
// class IrcManager;
// class ChannelManager
//{
// explicit ChannelManager();
// public:
// static ChannelManager &getInstance();
// const std::vector<ChannelPtr> getItems();
// const std::string &getUserID(const std::string &username);
// void doOnAll(std::function<void(ChannelPtr)> func);
// // Special channels
// const ChannelPtr whispersChannel;
// const ChannelPtr mentionsChannel;
// const ChannelPtr emptyChannel;
// void doOnAll(std::function<void(ChannelPtr)> func);
// void doOnAllNormalChannels(std::function<void(ChannelPtr)> func);
// private:
// std::map<std::string, std::string> usernameToID;
// std::map<std::string, ChannelData> channelDatas;
// QMutex channelsMutex;
// QMap<QString, std::tuple<std::shared_ptr<TwitchChannel>, int>> twitchChannels;
// pajlada::Signals::Signal<const QString &> ircJoin;
// pajlada::Signals::Signal<const QString &> ircPart;
// friend class singletons::IrcManager;
//};
//} // namespace singletons
//} // namespace chatterino

View file

@ -5,6 +5,7 @@
#include "singletons/accountmanager.hpp" #include "singletons/accountmanager.hpp"
#include "singletons/pathmanager.hpp" #include "singletons/pathmanager.hpp"
#include <QApplication>
#include <QFile> #include <QFile>
#include <QRegularExpression> #include <QRegularExpression>
@ -111,7 +112,13 @@ QString CommandManager::execCommand(const QString &text, ChannelPtr channel, boo
auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get()); auto *twitchChannel = dynamic_cast<TwitchChannel *>(channel.get());
if (!dryRun && twitchChannel != nullptr) { if (!dryRun && twitchChannel != nullptr) {
if (commandName == "/uptime") { if (commandName == "/debug-args") {
QString msg = QApplication::instance()->arguments().join(' ');
channel->addMessage(messages::Message::createSystemMessage(msg));
return "";
} else if (commandName == "/uptime") {
const auto &streamStatus = twitchChannel->GetStreamStatus(); const auto &streamStatus = twitchChannel->GetStreamStatus();
QString messageText = QString messageText =

View file

@ -1,28 +1,28 @@
#include "singletons/ircmanager.hpp" //#include "singletons/ircmanager.hpp"
#include "channel.hpp" //#include "channel.hpp"
#include "debug/log.hpp" //#include "debug/log.hpp"
#include "messages/messageparseargs.hpp" //#include "messages/messageparseargs.hpp"
#include "providers/twitch/twitchaccount.hpp" //#include "providers/twitch/twitchaccount.hpp"
#include "providers/twitch/twitchmessagebuilder.hpp" //#include "providers/twitch/twitchmessagebuilder.hpp"
#include "singletons/accountmanager.hpp" //#include "singletons/accountmanager.hpp"
#include "singletons/channelmanager.hpp" //#include "singletons/channelmanager.hpp"
#include "singletons/emotemanager.hpp" //#include "singletons/emotemanager.hpp"
#include "singletons/resourcemanager.hpp" //#include "singletons/resourcemanager.hpp"
#include "singletons/settingsmanager.hpp" //#include "singletons/settingsmanager.hpp"
#include "singletons/windowmanager.hpp" //#include "singletons/windowmanager.hpp"
#include "util/posttothread.hpp" //#include "util/posttothread.hpp"
#include "util/urlfetch.hpp" //#include "util/urlfetch.hpp"
#include <irccommand.h> //#include <irccommand.h>
#include <QJsonArray> //#include <QJsonArray>
#include <QJsonDocument> //#include <QJsonDocument>
#include <QJsonObject> //#include <QJsonObject>
#include <QNetworkReply> //#include <QNetworkReply>
#include <QNetworkRequest> //#include <QNetworkRequest>
#include <future> //#include <future>
using namespace chatterino::messages; //using namespace chatterino::messages;
// void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oauthClient, // void IrcManager::refreshIgnoredUsers(const QString &username, const QString &oauthClient,
// const QString &oauthToken) // const QString &oauthToken)

View file

@ -0,0 +1,115 @@
#include "nativemessagingmanager.hpp"
#include "singletons/pathmanager.hpp"
#include <QCoreApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
//#ifdef USEWINSDK
//#include <windows.h>
//#pragma comment(lib, "Advapi32.lib")
//#endif
#include <boost/interprocess/ipc/message_queue.hpp>
#ifdef Q_OS_WIN
#include <QProcess>
#endif
#define EXTENSION_ID "aeicjepmjkgmbeohnchmpfjbpchogmjn"
#define MESSAGE_SIZE 1024
namespace ipc = boost::interprocess;
namespace chatterino {
namespace singletons {
NativeMessagingManager::NativeMessagingManager()
{
}
NativeMessagingManager &NativeMessagingManager::getInstance()
{
static NativeMessagingManager manager;
return manager;
}
void NativeMessagingManager::registerHost()
{
// create manifest
QJsonDocument document;
QJsonObject root_obj;
root_obj.insert("name", "com.chatterino.chatterino");
root_obj.insert("description", "Browser interaction with chatterino.");
root_obj.insert("path", QCoreApplication::applicationFilePath());
root_obj.insert("type", "stdio");
QJsonArray allowed_origins_arr = {"chrome-extension://aeicjepmjkgmbeohnchmpfjbpchogmjn/"};
root_obj.insert("allowed_origins", allowed_origins_arr);
// save the manifest
QString manifestPath =
PathManager::getInstance().settingsFolderPath + "/native-messaging-manifest.json";
document.setObject(root_obj);
QFile file(manifestPath);
file.open(QIODevice::WriteOnly | QIODevice::Truncate);
file.write(document.toJson());
file.flush();
#ifdef Q_OS_WIN
// clang-format off
QProcess::execute("REG ADD \"HKCU\\Software\\Google\\Chrome\\NativeMessagingHosts\\com.chatterino.chatterino\" /ve /t REG_SZ /d \"" + manifestPath + "\" /f");
// clang-format on
#endif
}
void NativeMessagingManager::openGuiMessageQueue()
{
static ReceiverThread thread;
if (thread.isRunning()) {
thread.exit();
}
thread.start();
}
void NativeMessagingManager::sendToGuiProcess(const QByteArray &array)
{
ipc::message_queue messageQueue(ipc::open_only, "chatterino_gui");
try {
messageQueue.try_send(array.data(), array.size(), 1);
} catch (ipc::interprocess_exception &ex) {
// rip
}
}
void NativeMessagingManager::ReceiverThread::run()
{
ipc::message_queue::remove("chatterino_gui");
ipc::message_queue messageQueue(ipc::create_only, "chatterino_gui", 100, MESSAGE_SIZE);
while (true) {
try {
char *buf = (char *)malloc(MESSAGE_SIZE);
ipc::message_queue::size_type retSize;
unsigned int priority;
messageQueue.receive(buf, MESSAGE_SIZE, retSize, priority);
QString text = QString::fromUtf8(buf, retSize);
qDebug() << text;
} catch (ipc::interprocess_exception &ex) {
// rip
}
}
}
} // namespace singletons
} // namespace chatterino

View file

@ -0,0 +1,27 @@
#pragma once
#include <QThread>
namespace chatterino {
namespace singletons {
class NativeMessagingManager
{
NativeMessagingManager();
public:
static NativeMessagingManager &getInstance();
class ReceiverThread : public QThread
{
public:
void run() override;
};
void registerHost();
void openGuiMessageQueue();
void sendToGuiProcess(const QByteArray &array);
};
} // namespace singletons
} // namespace chatterino

View file

@ -2,7 +2,6 @@
#include "common.hpp" #include "common.hpp"
#include "debug/log.hpp" #include "debug/log.hpp"
#include "singletons/channelmanager.hpp"
#include "singletons/emotemanager.hpp" #include "singletons/emotemanager.hpp"
#include <QtAlgorithms> #include <QtAlgorithms>

View file

@ -4,7 +4,6 @@
#include "messages/limitedqueuesnapshot.hpp" #include "messages/limitedqueuesnapshot.hpp"
#include "messages/message.hpp" #include "messages/message.hpp"
#include "providers/twitch/twitchserver.hpp" #include "providers/twitch/twitchserver.hpp"
#include "singletons/channelmanager.hpp"
#include "singletons/settingsmanager.hpp" #include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp" #include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp" #include "singletons/windowmanager.hpp"

View file

@ -3,7 +3,6 @@
#include "providers/twitch/twitchchannel.hpp" #include "providers/twitch/twitchchannel.hpp"
#include "providers/twitch/twitchmessagebuilder.hpp" #include "providers/twitch/twitchmessagebuilder.hpp"
#include "providers/twitch/twitchserver.hpp" #include "providers/twitch/twitchserver.hpp"
#include "singletons/channelmanager.hpp"
#include "singletons/settingsmanager.hpp" #include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp" #include "singletons/thememanager.hpp"
#include "singletons/windowmanager.hpp" #include "singletons/windowmanager.hpp"

View file

@ -1,6 +1,5 @@
#include "widgets/window.hpp" #include "widgets/window.hpp"
#include "singletons/accountmanager.hpp" #include "singletons/accountmanager.hpp"
#include "singletons/channelmanager.hpp"
#include "singletons/ircmanager.hpp" #include "singletons/ircmanager.hpp"
#include "singletons/settingsmanager.hpp" #include "singletons/settingsmanager.hpp"
#include "singletons/thememanager.hpp" #include "singletons/thememanager.hpp"