linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06867
[Branch ~dcplusplus-team/dcpp-plugin-sdk-cpp/LoLPlugin] Rev 23: init
------------------------------------------------------------
revno: 23
committer: poy <poy@xxxxxxxxxx>
branch nick: LoLPlugin
timestamp: Thu 2013-05-16 19:47:44 +0200
message:
init
added:
src/AdcCommand.cpp
src/AdcCommand.h
src/GUI.cpp
src/GUI.h
modified:
src/Plugin.cpp
src/Plugin.h
src/resource.rc
src/stdafx.h
src/version.h
--
lp:~dcplusplus-team/dcpp-plugin-sdk-cpp/LoLPlugin
https://code.launchpad.net/~dcplusplus-team/dcpp-plugin-sdk-cpp/LoLPlugin
Your team Dcplusplus-team is subscribed to branch lp:~dcplusplus-team/dcpp-plugin-sdk-cpp/LoLPlugin.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcpp-plugin-sdk-cpp/LoLPlugin/+edit-subscription
=== added file 'src/AdcCommand.cpp'
--- src/AdcCommand.cpp 1970-01-01 00:00:00 +0000
+++ src/AdcCommand.cpp 2013-05-16 17:47:44 +0000
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2001-2013 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "AdcCommand.h"
+
+namespace dcpp {
+
+AdcCommand::AdcCommand(uint32_t aCmd, char aType /* = TYPE_CLIENT */) : cmdInt(aCmd), from(0), type(aType) { }
+AdcCommand::AdcCommand(uint32_t aCmd, const uint32_t aTarget, char aType) : cmdInt(aCmd), from(0), to(aTarget), type(aType) { }
+
+AdcCommand::AdcCommand(const string& aLine, bool nmdc /* = false */) : cmdInt(0), type(TYPE_CLIENT) {
+ parse(aLine, nmdc);
+}
+
+void AdcCommand::parse(const string& aLine, bool nmdc /* = false */) {
+ string::size_type i = 5;
+
+ if(nmdc) {
+ // "$ADCxxx ..."
+ if(aLine.length() < 7)
+ return;
+ type = TYPE_CLIENT;
+ cmd[0] = aLine[4];
+ cmd[1] = aLine[5];
+ cmd[2] = aLine[6];
+ i += 3;
+ } else {
+ // "yxxx ..."
+ if(aLine.length() < 4)
+ return;
+ type = aLine[0];
+ cmd[0] = aLine[1];
+ cmd[1] = aLine[2];
+ cmd[2] = aLine[3];
+ }
+
+ if(type != TYPE_BROADCAST && type != TYPE_CLIENT && type != TYPE_DIRECT && type != TYPE_ECHO && type != TYPE_FEATURE && type != TYPE_INFO && type != TYPE_HUB && type != TYPE_UDP) {
+ return;
+ }
+
+ if(type == TYPE_INFO) {
+ from = HUB_SID;
+ }
+
+ string::size_type len = aLine.length();
+ const char* buf = aLine.c_str();
+ string cur;
+ cur.reserve(128);
+
+ bool toSet = false;
+ bool featureSet = false;
+ bool fromSet = nmdc; // $ADCxxx never have a from CID...
+
+ while(i < len) {
+ switch(buf[i]) {
+ case '\\':
+ ++i;
+ if(i == len)
+ return;
+ if(buf[i] == 's')
+ cur += ' ';
+ else if(buf[i] == 'n')
+ cur += '\n';
+ else if(buf[i] == '\\')
+ cur += '\\';
+ else if(buf[i] == ' ' && nmdc) // $ADCGET escaping, leftover from old specs
+ cur += ' ';
+ else
+ return;
+ break;
+ case ' ':
+ // New parameter...
+ {
+ if((type == TYPE_BROADCAST || type == TYPE_DIRECT || type == TYPE_ECHO || type == TYPE_FEATURE) && !fromSet) {
+ if(cur.length() != 4) {
+ return;
+ }
+ from = toSID(cur);
+ fromSet = true;
+ } else if((type == TYPE_DIRECT || type == TYPE_ECHO) && !toSet) {
+ if(cur.length() != 4) {
+ return;
+ }
+ to = toSID(cur);
+ toSet = true;
+ } else if(type == TYPE_FEATURE && !featureSet) {
+ if(cur.length() % 5 != 0) {
+ return;
+ }
+ // Skip...
+ featureSet = true;
+ } else {
+ parameters.push_back(cur);
+ }
+ cur.clear();
+ }
+ break;
+ default:
+ cur += buf[i];
+ }
+ ++i;
+ }
+ if(!cur.empty()) {
+ if((type == TYPE_BROADCAST || type == TYPE_DIRECT || type == TYPE_ECHO || type == TYPE_FEATURE) && !fromSet) {
+ if(cur.length() != 4) {
+ return;
+ }
+ from = toSID(cur);
+ fromSet = true;
+ } else if((type == TYPE_DIRECT || type == TYPE_ECHO) && !toSet) {
+ if(cur.length() != 4) {
+ return;
+ }
+ to = toSID(cur);
+ toSet = true;
+ } else if(type == TYPE_FEATURE && !featureSet) {
+ if(cur.length() % 5 != 0) {
+ return;
+ }
+ // Skip...
+ featureSet = true;
+ } else {
+ parameters.push_back(cur);
+ }
+ }
+
+ if((type == TYPE_BROADCAST || type == TYPE_DIRECT || type == TYPE_ECHO || type == TYPE_FEATURE) && !fromSet) {
+ return;
+ }
+
+ if(type == TYPE_FEATURE && !featureSet) {
+ return;
+ }
+
+ if((type == TYPE_DIRECT || type == TYPE_ECHO) && !toSet) {
+ return;
+ }
+}
+
+string AdcCommand::toString(uint32_t sid /* = 0 */, bool nmdc /* = false */) const {
+ return getHeaderString(sid, nmdc) + getParamString(nmdc);
+}
+
+string AdcCommand::escape(const string& str, bool old) {
+ string tmp = str;
+ string::size_type i = 0;
+ while( (i = tmp.find_first_of(" \n\\", i)) != string::npos) {
+ if(old) {
+ tmp.insert(i, "\\");
+ } else {
+ switch(tmp[i]) {
+ case ' ': tmp.replace(i, 1, "\\s"); break;
+ case '\n': tmp.replace(i, 1, "\\n"); break;
+ case '\\': tmp.replace(i, 1, "\\\\"); break;
+ }
+ }
+ i+=2;
+ }
+ return tmp;
+}
+
+string AdcCommand::getHeaderString(uint32_t sid, bool nmdc) const {
+ string tmp;
+ if(nmdc) {
+ tmp += "$ADC";
+ } else {
+ tmp += getType();
+ }
+
+ tmp += cmdChar;
+
+ if(type == TYPE_BROADCAST || type == TYPE_DIRECT || type == TYPE_ECHO || type == TYPE_FEATURE) {
+ tmp += ' ';
+ tmp += fromSID(sid);
+ }
+
+ if(type == TYPE_DIRECT || type == TYPE_ECHO) {
+ tmp += ' ';
+ tmp += fromSID(to);
+ }
+
+ if(type == TYPE_FEATURE) {
+ tmp += ' ';
+ tmp += features;
+ }
+ return tmp;
+}
+
+string AdcCommand::getParamString(bool nmdc) const {
+ string tmp;
+ for(auto& i: getParameters()) {
+ tmp += ' ';
+ tmp += escape(i, nmdc);
+ }
+ if(nmdc) {
+ tmp += '|';
+ } else {
+ tmp += '\n';
+ }
+ return tmp;
+}
+
+const string& AdcCommand::getParam(size_t n) const {
+ return getParameters().size() > n ? getParameters()[n] : emptyString;
+}
+
+bool AdcCommand::getParam(const char* name, size_t start, string& ret) const {
+ for(auto i = start; i < getParameters().size(); ++i) {
+ if(toCode(name) == toCode(getParameters()[i].c_str())) {
+ ret = getParameters()[i].substr(2);
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AdcCommand::hasFlag(const char* name, size_t start) const {
+ for(auto i = start; i < getParameters().size(); ++i) {
+ if(toCode(name) == toCode(getParameters()[i].c_str()) &&
+ getParameters()[i].size() == 3 &&
+ getParameters()[i][2] == '1')
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace dcpp
=== added file 'src/AdcCommand.h'
--- src/AdcCommand.h 1970-01-01 00:00:00 +0000
+++ src/AdcCommand.h 2013-05-16 17:47:44 +0000
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2001-2013 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef DCPLUSPLUS_DCPP_ADC_COMMAND_H
+#define DCPLUSPLUS_DCPP_ADC_COMMAND_H
+
+#include <cstdint>
+#include <string>
+#include <vector>
+
+namespace dcpp {
+
+using std::string;
+typedef std::vector<string> StringList;
+
+class AdcCommand {
+public:
+ template<uint32_t T>
+ struct Type {
+ enum { CMD = T };
+ };
+
+ enum Error {
+ SUCCESS = 0,
+ ERROR_GENERIC = 0,
+ ERROR_HUB_GENERIC = 10,
+ ERROR_HUB_FULL = 11,
+ ERROR_HUB_DISABLED = 12,
+ ERROR_LOGIN_GENERIC = 20,
+ ERROR_NICK_INVALID = 21,
+ ERROR_NICK_TAKEN = 22,
+ ERROR_BAD_PASSWORD = 23,
+ ERROR_CID_TAKEN = 24,
+ ERROR_COMMAND_ACCESS = 25,
+ ERROR_REGGED_ONLY = 26,
+ ERROR_INVALID_PID = 27,
+ ERROR_BANNED_GENERIC = 30,
+ ERROR_PERM_BANNED = 31,
+ ERROR_TEMP_BANNED = 32,
+ ERROR_PROTOCOL_GENERIC = 40,
+ ERROR_PROTOCOL_UNSUPPORTED = 41,
+ ERROR_CONNECT_FAILED = 42,
+ ERROR_INF_MISSING = 43,
+ ERROR_BAD_STATE = 44,
+ ERROR_FEATURE_MISSING = 45,
+ ERROR_BAD_IP = 46,
+ ERROR_NO_HUB_HASH = 47,
+ ERROR_TRANSFER_GENERIC = 50,
+ ERROR_FILE_NOT_AVAILABLE = 51,
+ ERROR_FILE_PART_NOT_AVAILABLE = 52,
+ ERROR_SLOTS_FULL = 53,
+ ERROR_NO_CLIENT_HASH = 54
+ };
+
+ enum Severity {
+ SEV_SUCCESS = 0,
+ SEV_RECOVERABLE = 1,
+ SEV_FATAL = 2
+ };
+
+ static const char TYPE_BROADCAST = 'B';
+ static const char TYPE_CLIENT = 'C';
+ static const char TYPE_DIRECT = 'D';
+ static const char TYPE_ECHO = 'E';
+ static const char TYPE_FEATURE = 'F';
+ static const char TYPE_INFO = 'I';
+ static const char TYPE_HUB = 'H';
+ static const char TYPE_UDP = 'U';
+
+#if defined(_WIN32) || defined(__i386__) || defined(__x86_64__) || defined(__alpha)
+#define C(n, a, b, c) static const uint32_t CMD_##n = (((uint32_t)a) | (((uint32_t)b)<<8) | (((uint32_t)c)<<16)); typedef Type<CMD_##n> n
+#else
+#define C(n, a, b, c) static const uint32_t CMD_##n = ((((uint32_t)a)<<24) | (((uint32_t)b)<<16) | (((uint32_t)c)<<8)); typedef Type<CMD_##n> n
+#endif
+ // Base commands
+ C(SUP, 'S','U','P');
+ C(STA, 'S','T','A');
+ C(INF, 'I','N','F');
+ C(MSG, 'M','S','G');
+ C(SCH, 'S','C','H');
+ C(RES, 'R','E','S');
+ C(CTM, 'C','T','M');
+ C(RCM, 'R','C','M');
+ C(GPA, 'G','P','A');
+ C(PAS, 'P','A','S');
+ C(QUI, 'Q','U','I');
+ C(GET, 'G','E','T');
+ C(GFI, 'G','F','I');
+ C(SND, 'S','N','D');
+ C(SID, 'S','I','D');
+ // Extensions
+ C(CMD, 'C','M','D');
+ C(NAT, 'N','A','T');
+ C(RNT, 'R','N','T');
+ C(ZON, 'Z','O','N');
+ C(ZOF, 'Z','O','F');
+ C(LOL, 'L','O','L');
+#undef C
+
+ static const uint32_t HUB_SID = 0xffffffff; // No client will have this sid
+
+ static uint32_t toFourCC(const char* x) { return *reinterpret_cast<const uint32_t*>(x); }
+ static std::string fromFourCC(uint32_t x) { return std::string(reinterpret_cast<const char*>(&x), sizeof(x)); }
+
+ explicit AdcCommand(uint32_t aCmd, char aType = TYPE_CLIENT);
+ explicit AdcCommand(uint32_t aCmd, const uint32_t aTarget, char aType);
+ explicit AdcCommand(const string& aLine, bool nmdc = false);
+ void parse(const string& aLine, bool nmdc = false);
+
+ uint32_t getCommand() const { return cmdInt; }
+ char getType() const { return type; }
+ void setType(char t) { type = t; }
+ string getFourCC() const { string tmp(4, 0); tmp[0] = type; tmp[1] = cmd[0]; tmp[2] = cmd[1]; tmp[3] = cmd[2]; return tmp; }
+
+ const string& getFeatures() const { return features; }
+ AdcCommand& setFeatures(const string& feat) { features = feat; return *this; }
+
+ StringList& getParameters() { return parameters; }
+ const StringList& getParameters() const { return parameters; }
+
+ string toString(uint32_t sid = 0, bool nmdc = false) const;
+
+ AdcCommand& addParam(const string& name, const string& value) {
+ parameters.push_back(name);
+ parameters.back() += value;
+ return *this;
+ }
+ AdcCommand& addParam(const string& str) {
+ parameters.push_back(str);
+ return *this;
+ }
+ const string& getParam(size_t n) const;
+ /** Return a named parameter where the name is a two-letter code */
+ bool getParam(const char* name, size_t start, string& ret) const;
+ bool hasFlag(const char* name, size_t start) const;
+ static uint16_t toCode(const char* x) { return *((uint16_t*)x); }
+
+ bool operator==(uint32_t aCmd) { return cmdInt == aCmd; }
+
+ static string escape(const string& str, bool old);
+ uint32_t getTo() const { return to; }
+ AdcCommand& setTo(const uint32_t sid) { to = sid; return *this; }
+ uint32_t getFrom() const { return from; }
+
+ static uint32_t toSID(const string& aSID) { return *reinterpret_cast<const uint32_t*>(aSID.data()); }
+ static string fromSID(const uint32_t aSID) { return string(reinterpret_cast<const char*>(&aSID), sizeof(aSID)); }
+private:
+ string getHeaderString(uint32_t sid, bool nmdc) const;
+ string getParamString(bool nmdc) const;
+ StringList parameters;
+ string features;
+ union {
+ char cmdChar[4];
+ uint8_t cmd[4];
+ uint32_t cmdInt;
+ };
+ uint32_t from;
+ uint32_t to;
+ char type;
+ string emptyString;
+};
+
+} // namespace dcpp
+
+#endif // !defined(ADC_COMMAND_H)
=== added file 'src/GUI.cpp'
--- src/GUI.cpp 1970-01-01 00:00:00 +0000
+++ src/GUI.cpp 2013-05-16 17:47:44 +0000
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2012-2013 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "stdafx.h"
+#include "GUI.h"
+#include "Plugin.h"
+
+#include <pluginsdk/Config.h>
+#include <pluginsdk/Util.h>
+
+#include <dwt/Application.h>
+#include <dwt/DWTException.h>
+#include <dwt/Events.h>
+#include <dwt/widgets/Button.h>
+#include <dwt/widgets/ComboBox.h>
+#include <dwt/widgets/Grid.h>
+#include <dwt/widgets/GroupBox.h>
+#include <dwt/widgets/Label.h>
+#include <dwt/widgets/TextBox.h>
+#include <dwt/widgets/Window.h>
+
+// dwt defines another tstring...
+typedef tstring _tstring;
+#define tstring _tstring
+
+using dcapi::Config;
+using dcapi::Util;
+
+using namespace dwt;
+
+WindowPtr window;
+ComboBoxPtr server;
+TextBoxPtr summoner;
+TextBoxPtr link;
+
+GUI::GUI()
+{
+}
+
+GUI::~GUI() {
+ if(window) {
+ ::DestroyWindow(window->handle());
+ window = nullptr;
+ Application::uninit();
+ }
+}
+
+void GUI::create() {
+ if(window) {
+ return;
+ }
+
+ Application::init();
+
+ {
+ Window::Seed seed(_T(PLUGIN_NAME));
+ seed.location.size.x = 600;
+ seed.location.size.y = 300;
+
+ window = new Window();
+ window->create(seed);
+
+ auto iconPath = Util::toT(Config::getInstallPath() + "LoLPlugin.ico");
+ try {
+ window->setSmallIcon(new dwt::Icon(iconPath, dwt::Point(16, 16)));
+ window->setLargeIcon(new dwt::Icon(iconPath, dwt::Point(32, 32)));
+ } catch(const dwt::DWTException&) { }
+
+ window->onClosing([]() -> bool {
+ window = nullptr;
+ Application::uninit();
+ return true;
+ });
+ }
+
+ auto grid = window->addChild(Grid::Seed(3, 1));
+ grid->column(0).mode = GridInfo::FILL;
+ grid->setSpacing(6);
+
+ {
+ auto cur = grid->addChild(GroupBox::Seed(_T("Your LoL information")))->addChild(Grid::Seed(2, 1));
+ cur->column(0).mode = GridInfo::FILL;
+ cur->setSpacing(grid->getSpacing());
+
+ ComboBox::Seed cs;
+ cs.style |= CBS_DROPDOWNLIST;
+ server = cur->addChild(GroupBox::Seed(_T("The server you play on")))->addChild(cs);
+ const auto servConf = Config::getConfig("Server");
+ size_t counter = 0, sel = 0;
+ for(auto& serv: Plugin::servers) {
+ server->addValue(Util::toT(serv));
+ if(serv == servConf) { sel = counter; }
+ ++counter;
+ }
+ server->setSelected(sel);
+
+ TextBox::Seed ts(Util::toT(Config::getConfig("Summoner")));
+ ts.style |= ES_AUTOHSCROLL;
+ summoner = cur->addChild(GroupBox::Seed(_T("Your summoner name")))->addChild(ts);
+ }
+
+ {
+ auto cur = grid->addChild(GroupBox::Seed(_T("Web link to display LoL information")))->addChild(Grid::Seed(3, 1));
+ cur->column(0).mode = GridInfo::FILL;
+ cur->setSpacing(grid->getSpacing());
+
+ auto row = cur->addChild(Grid::Seed(1, 2));
+ row->column(0).mode = GridInfo::FILL;
+ row->setSpacing(cur->getSpacing());
+
+ auto confLink = Config::getConfig("Link");
+ if(confLink.empty()) { confLink = Plugin::defLink; }
+ TextBox::Seed seed(Util::toT(confLink));
+ seed.style |= ES_AUTOHSCROLL;
+ link = row->addChild(seed);
+
+ row->addChild(Button::Seed(_T("Default link")))->onClicked([] { link->setText(Util::toT(Plugin::defLink)); });
+
+ cur->addChild(Label::Seed(_T("<server> will be replaced by the user's LoL server.")));
+ cur->addChild(Label::Seed(_T("<summoner> will be replaced by the user's LoL summoner name.")));
+ }
+
+ {
+ auto cur = grid->addChild(Grid::Seed(1, 2));
+ cur->column(0).mode = GridInfo::FILL;
+ cur->column(0).align = GridInfo::BOTTOM_RIGHT;
+ cur->setSpacing(grid->getSpacing());
+
+ Button::Seed bs(_T("OK"));
+ bs.style |= BS_DEFPUSHBUTTON;
+ bs.padding.x = 20;
+ cur->addChild(bs)->onClicked([this] { ok(); });
+
+ bs.caption = _T("Cancel");
+ bs.style &= ~BS_DEFPUSHBUTTON;
+ bs.padding.x = 10;
+ cur->addChild(bs)->onClicked([] { window->close(true); });
+ }
+
+ grid->resize(window->getClientSize());
+ window->onSized([grid](const SizedEvent& e) { grid->resize(e.size); });
+}
+
+void GUI::ok() {
+ Config::setConfig("Server", Util::fromT(server->getText()));
+ Config::setConfig("Summoner", Util::fromT(summoner->getText()));
+ Config::setConfig("Link", Util::fromT(link->getText()));
+ if(Config::getConfig("Link").empty()) { Config::setConfig("Link", Plugin::defLink); }
+
+ window->close(true);
+}
=== added file 'src/GUI.h'
--- src/GUI.h 1970-01-01 00:00:00 +0000
+++ src/GUI.h 2013-05-16 17:47:44 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012-2013 Jacek Sieka, arnetheduck on gmail point com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef PLUGIN_GUI_H
+#define PLUGIN_GUI_H
+
+class GUI
+{
+public:
+ GUI();
+ ~GUI();
+
+ void create();
+
+private:
+ void ok();
+};
+
+#endif
=== modified file 'src/Plugin.cpp'
--- src/Plugin.cpp 2013-01-18 21:37:14 +0000
+++ src/Plugin.cpp 2013-05-16 17:47:44 +0000
@@ -19,21 +19,40 @@
#include "stdafx.h"
#include "Plugin.h"
+#include <boost/algorithm/string/replace.hpp>
+
/* Include plugin SDK helpers. There are more interfaces available that can be included in the same
fashion (check the pluginsdk directory). */
#include <pluginsdk/Config.h>
#include <pluginsdk/Core.h>
#include <pluginsdk/Hooks.h>
+#include <pluginsdk/Hubs.h>
#include <pluginsdk/Logger.h>
+#include <pluginsdk/UI.h>
#include <pluginsdk/Util.h>
+#include "AdcCommand.h"
+
+#include <shellapi.h>
+
/* Plugin SDK helpers are in the "dcapi" namespace; ease their calling. */
using dcapi::Config;
using dcapi::Core;
using dcapi::Hooks;
+using dcapi::Hubs;
using dcapi::Logger;
+using dcapi::UI;
using dcapi::Util;
+using dcpp::AdcCommand;
+
+const string feat = "LOLI";
+
+const string Plugin::defLink = "http://quickfind.kassad.in/profile/<server>/<summoner>/";
+const string Plugin::servers[7] = { "br", "eune", "euw", "kr", "na", "ru", "tr" };
+
+const size_t MAX_CACHE = 10;
+
Plugin::Plugin() {
}
@@ -60,6 +79,12 @@
return True;
}
+ case ON_CONFIGURE:
+ {
+ instance->onConfigure();
+ return True;
+ }
+
default:
{
return False;
@@ -71,15 +96,110 @@
/* Initialization phase. Initiate additional interfaces that you may have included from the
plugin SDK. */
Core::init(core);
- if(!Config::init(PLUGIN_GUID) || !Hooks::init() || !Logger::init() || !Util::init()) {
+ if(!Config::init(PLUGIN_GUID) || !Hooks::init() || !Hubs::init() || !Logger::init() || !UI::init(PLUGIN_GUID) || !Util::init()) {
return false;
}
+ if(Config::getConfig("Link").empty()) { Config::setConfig("Link", defLink); }
+
if(install) {
// This only executes when the plugin has been installed for the first time.
+ Logger::log("The LoL plugin has been installed; check the plugins menu to configure it.");
+
+ onConfigure();
+ }
+
+ if(Config::getConfig("Server").empty() || Config::getConfig("Summoner").empty()) {
+ Logger::log("LoL plugin: You have not defined your LoL settings; use the plugins menu to configure them.");
}
// Start the plugin logic here; add hooks with functions from the Hooks interface.
+ Hooks::Network::onHubDataIn([this](HubDataPtr hub, char* message, bool&) { return onHubDataIn(hub, message); });
+ Hooks::Network::onHubDataOut([this](HubDataPtr hub, char* message, bool&) { return onHubDataOut(hub, message); });
return true;
}
+
+void Plugin::onConfigure() {
+ gui.create();
+}
+
+namespace {
+#ifdef _WIN32
+void openLink(const string& link) {
+ ShellExecute(nullptr, nullptr, Util::toT(link).c_str(), nullptr, nullptr, SW_SHOWNORMAL);
+}
+#else
+void openLink(const string& link) {
+ system(string("xdg-open " + link).c_str());
+}
+#endif
+} // unnamed namespace
+
+bool Plugin::onHubDataIn(HubDataPtr hub, char* message) {
+ if(hub->protocol == PROTOCOL_ADC) {
+ auto cmd = AdcCommand(message);
+
+ if(cmd.getCommand() == AdcCommand::CMD_SID && cmd.getType() == AdcCommand::TYPE_INFO) {
+ // add the user command.
+ Hubs::handle()->emulate_protocol_cmd(hub,
+ AdcCommand(AdcCommand::CMD_CMD, AdcCommand::TYPE_INFO)
+ .addParam("Open LoL profile")
+ .addParam("CT", "14" /* 2 + 4 + 8 */)
+ .addParam("TT", "DLOL %[mySID] %[userSID]\n")
+ .addParam("CO", "1")
+ .toString().c_str());
+
+ } else if(cmd.getCommand() == AdcCommand::CMD_LOL && cmd.getType() == AdcCommand::TYPE_DIRECT) {
+ if(cmd.getParameters().empty()) {
+ // answer with our LoL info.
+ Hubs::handle()->send_protocol_cmd(hub,
+ AdcCommand(AdcCommand::CMD_LOL, cmd.getFrom(), AdcCommand::TYPE_DIRECT)
+ .addParam("SE", Config::getConfig("Server"))
+ .addParam("SU", Config::getConfig("Summoner"))
+ .toString(cmd.getTo()).c_str());
+
+ } else {
+ if(std::find(cache.begin(), cache.end(), cmd.getFrom()) != cache.end()) {
+ string server, summoner;
+ if(cmd.getParam("SE", 0, server) && cmd.getParam("SU", 0, summoner)) {
+ auto link = Config::getConfig("Link");
+ boost::ireplace_first(link, "<server>", server);
+ boost::ireplace_first(link, "<summoner>", summoner);
+ openLink(link);
+ }
+ }
+ }
+ }
+
+ } else if(hub->protocol == PROTOCOL_NMDC) {
+ // TODO fuck NMDC?
+ }
+ return false;
+}
+
+bool Plugin::onHubDataOut(HubDataPtr hub, char* message) {
+ if(hub->protocol == PROTOCOL_ADC) {
+ auto cmd = AdcCommand(message);
+
+ if(cmd.getCommand() == AdcCommand::CMD_INF) {
+ // add the feature to INF SU.
+ auto& params = cmd.getParameters();
+ for(auto& param: params) {
+ if(AdcCommand::toCode(param.c_str()) == AdcCommand::toCode("SU") && param.find(feat) == string::npos) {
+ param += ',' + feat;
+ }
+ }
+
+ } else if(cmd.getCommand() == AdcCommand::CMD_LOL) {
+ if(cache.size() > MAX_CACHE) {
+ cache.erase(cache.begin(), cache.begin() + MAX_CACHE / 2);
+ }
+ cache.push_back(cmd.getTo());
+ }
+
+ } else if(hub->protocol == PROTOCOL_NMDC) {
+ // TODO fuck NMDC?
+ }
+ return false;
+}
=== modified file 'src/Plugin.h'
--- src/Plugin.h 2013-01-18 21:37:14 +0000
+++ src/Plugin.h 2013-05-16 17:47:44 +0000
@@ -19,18 +19,31 @@
#ifndef PLUGIN_PLUGIN_H
#define PLUGIN_PLUGIN_H
-using std::string;
+#include <vector>
+
+#include "GUI.h"
class Plugin
{
public:
static Bool DCAPI main(PluginState state, DCCorePtr core, dcptr_t);
+ static const string defLink;
+ static const string servers[7];
+
private:
Plugin();
~Plugin();
bool onLoad(DCCorePtr core, bool install);
+ void onConfigure();
+ bool onHubDataIn(HubDataPtr hub, char* message);
+ bool onHubDataOut(HubDataPtr hub, char* message);
+
+ // dumb cache to make sure people don't spam us with random LOLs...
+ std::vector<uint32_t> cache;
+
+ GUI gui;
};
#endif
=== modified file 'src/resource.rc'
--- src/resource.rc 2012-11-15 18:17:16 +0000
+++ src/resource.rc 2013-05-16 17:47:44 +0000
@@ -67,13 +67,13 @@
BEGIN
BLOCK "080004b0"
BEGIN
- VALUE "Comments", "..."
- VALUE "FileDescription", "..."
+ VALUE "Comments", "http://dcplusplus.sourceforge.net"
+ VALUE "FileDescription", "LoL plugin for DC++"
VALUE "FileVersion", "1, 0, 0, 0"
- VALUE "InternalName", "..."
- VALUE "LegalCopyright", "..."
- VALUE "OriginalFilename", "..."
- VALUE "ProductName", "..."
+ VALUE "InternalName", "LoLPlugin"
+ VALUE "LegalCopyright", "Copyright (C) 2012-2013 Jacek Sieka"
+ VALUE "OriginalFilename", "LoLPlugin.dll"
+ VALUE "ProductName", "LoL plugin for DC++"
VALUE "ProductVersion", "1, 0, 0, 0"
END
END
=== modified file 'src/stdafx.h'
--- src/stdafx.h 2013-01-18 21:37:14 +0000
+++ src/stdafx.h 2013-05-16 17:47:44 +0000
@@ -33,6 +33,7 @@
#include <cstdio>
#include <cstdint>
#include <string>
+#include <utility>
#include <pluginsdk/PluginDefs.h>
@@ -44,4 +45,7 @@
typedef std::string tstring;
#endif
+using std::move;
+using std::string;
+
#endif
=== modified file 'src/version.h'
--- src/version.h 2013-01-18 21:37:14 +0000
+++ src/version.h 2013-05-16 17:47:44 +0000
@@ -18,27 +18,25 @@
/* Information about the plugin - fill this out! Don't forget to edit the resource file as well. */
-#error Version information not set! Remove this error once you have filled version.h and the resource file.
-
#ifndef PLUGIN_VERSION_H
#define PLUGIN_VERSION_H
/* UUID/GUID for this plugin project */
-#define PLUGIN_GUID "..."
+#define PLUGIN_GUID "{32c71f4f-ea2f-40ea-a5c9-52e46e721bbc}"
/* Name of the plugin */
-#define PLUGIN_NAME "..."
+#define PLUGIN_NAME "LoL plugin"
/* Author of the plugin */
-#define PLUGIN_AUTHOR "..."
+#define PLUGIN_AUTHOR "DC++"
/* Short description of the plugin */
-#define PLUGIN_DESC "..."
+#define PLUGIN_DESC "Exchange League of Legends profile information with other users."
/* Version of the plugin (note: not API version) */
#define PLUGIN_VERSION 1.0
/* Plugin website, set to "N/A" if none */
-#define PLUGIN_WEB "N/A"
+#define PLUGIN_WEB "http://dcplusplus.sourceforge.net/"
#endif