← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3133: update the script plugin

 

------------------------------------------------------------
revno: 3133
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-11-11 18:43:20 +0100
message:
  update the script plugin
modified:
  plugins/Dev/pluginsdk.cpp
  plugins/Script/Plugin.cpp
  plugins/Script/Plugin.h
  plugins/Script/pluginsdk.cpp
  plugins/Test/pluginsdk.cpp
  pluginsdk/cpp/pluginsdk/Hooks.cpp
  pluginsdk/cpp/pluginsdk/Hooks.h


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'plugins/Dev/pluginsdk.cpp'
--- plugins/Dev/pluginsdk.cpp	2012-11-11 16:57:44 +0000
+++ plugins/Dev/pluginsdk.cpp	2012-11-11 17:43:20 +0000
@@ -3,8 +3,8 @@
 
 #include "version.h"
 
+#include <pluginsdk/Config.cpp>
 #include <pluginsdk/Core.cpp>
-#include <pluginsdk/Config.cpp>
 #include <pluginsdk/Hooks.cpp>
 #include <pluginsdk/Hubs.cpp>
 #include <pluginsdk/Logger.cpp>

=== modified file 'plugins/Script/Plugin.cpp'
--- plugins/Script/Plugin.cpp	2012-11-11 15:12:15 +0000
+++ plugins/Script/Plugin.cpp	2012-11-11 17:43:20 +0000
@@ -20,14 +20,20 @@
 #include "Plugin.h"
 
 #include <pluginsdk/Config.h>
+#include <pluginsdk/Connections.h>
 #include <pluginsdk/Core.h>
+#include <pluginsdk/Hooks.h>
+#include <pluginsdk/Hubs.h>
 #include <pluginsdk/Logger.h>
 #include <pluginsdk/Util.h>
 
 #include <boost/filesystem/operations.hpp>
 
 using dcapi::Config;
+using dcapi::Connections;
 using dcapi::Core;
+using dcapi::Hooks;
+using dcapi::Hubs;
 using dcapi::Logger;
 using dcapi::Util;
 
@@ -39,17 +45,15 @@
 	if(L) {
 		if(!hubs.empty()) {
 			for(auto& i: hubs) {
-				hub->remove_hub(i);
-				hub->release(i);
+				Hubs::handle()->remove_hub(i);
+				Hubs::handle()->release(i);
 			}
 
 			Logger::log("Script plugin warning: scripts do not correctly remove hubs they add!");
 			hubs.clear();
 		}
 
-		for(auto& i: events)
-			hooks->release_hook(i.second);
-		events.clear();
+		Hooks::clear();
 
 		chatCache.clear();
 
@@ -62,10 +66,8 @@
 	case ON_INSTALL:
 	case ON_LOAD:
 		{
-			Bool res = True;
 			instance = new Plugin();
-			instance->onLoad(core, (state == ON_INSTALL), res);
-			return res;
+			return instance->onLoad(core, state == ON_INSTALL) ? True : False;
 		}
 
 	case ON_UNINSTALL:
@@ -83,17 +85,11 @@
 	}
 }
 
-void Plugin::onLoad(DCCorePtr core, bool install, Bool& loadRes) {
-	hooks = reinterpret_cast<DCHooksPtr>(core->query_interface(DCINTF_HOOKS, DCINTF_HOOKS_VER));
-
-	hub = reinterpret_cast<DCHubPtr>(core->query_interface(DCINTF_DCPP_HUBS, DCINTF_DCPP_HUBS_VER));
-	connection = reinterpret_cast<DCConnectionPtr>(core->query_interface(DCINTF_DCPP_CONNECTIONS, DCINTF_DCPP_CONNECTIONS_VER));
-
-	if(!Util::init(core) || !Config::init(core) || !Logger::init(core) || !hooks || !hub || !connection) {
-		loadRes = False;
-		return;
-	}
+bool Plugin::onLoad(DCCorePtr core, bool install) {
 	Core::init(core);
+	if(!Config::init() || !Connections::init() || !Hooks::init() || !Hubs::init() || !Logger::init() || !Util::init()) {
+		return false;
+	}
 
 	// Default settings
 	if(Config::getConfig("ScriptPath").empty()) {
@@ -110,7 +106,7 @@
 
 	if(install) {
 		Logger::log("Script plugin installed, please restart " + Core::appName + " to begin using the plugin.");
-		return;
+		return true;
 	}
 
 	L = luaL_newstate();
@@ -124,25 +120,17 @@
 	Lunar<LuaManager>::Register(L);
 	lua_pop(L, lua_gettop(L));
 
-	events[HOOK_CHAT_OUT] = hooks->bind_hook(HOOK_CHAT_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onOwnChatOut(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
-
-	events[HOOK_HUB_ONLINE] = hooks->bind_hook(HOOK_HUB_ONLINE, [](dcptr_t pObject, dcptr_t, dcptr_t, Bool*) {
-		return instance->onHubConnected(reinterpret_cast<HubDataPtr>(pObject)); }, nullptr);
-	events[HOOK_HUB_OFFLINE] = hooks->bind_hook(HOOK_HUB_OFFLINE, [](dcptr_t pObject, dcptr_t, dcptr_t, Bool*) {
-		return instance->onHubDisconnected(reinterpret_cast<HubDataPtr>(pObject)); }, nullptr);
-
-	events[HOOK_NETWORK_HUB_IN] = hooks->bind_hook(HOOK_NETWORK_HUB_IN, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onHubDataIn(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
-	events[HOOK_NETWORK_HUB_OUT] = hooks->bind_hook(HOOK_NETWORK_HUB_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* bBreak) {
-		return instance->onHubDataOut(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); }, nullptr);
-	events[HOOK_NETWORK_CONN_IN] = hooks->bind_hook(HOOK_NETWORK_CONN_IN, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onConnectionDataIn(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
-	events[HOOK_NETWORK_CONN_OUT] = hooks->bind_hook(HOOK_NETWORK_CONN_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onConnectionDataOut(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
-
-	events[HOOK_UI_CHAT_COMMAND] = hooks->bind_hook(HOOK_UI_CHAT_COMMAND, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onHubEnter(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<CommandDataPtr>(pData)); }, nullptr);
+	Hooks::Chat::onOutgoingChat([this](HubDataPtr hub, char* msg, bool&) { return onOwnChatOut(hub, msg); });
+
+	Hooks::Hubs::onOnline([this](HubDataPtr hub, bool&) { return onHubConnected(hub); });
+	Hooks::Hubs::onOffline([this](HubDataPtr hub, bool&) { return onHubDisconnected(hub); });
+
+	Hooks::Network::onHubDataIn([this](HubDataPtr hub, char* msg, bool&) { return onHubDataIn(hub, msg); });
+	Hooks::Network::onHubDataOut([this](HubDataPtr hub, char* msg, bool& bBreak) { return onHubDataOut(hub, msg, bBreak); });
+	Hooks::Network::onClientDataIn([this](ConnectionDataPtr conn, char* msg, bool&) { return onConnectionDataIn(conn, msg); });
+	Hooks::Network::onClientDataOut([this](ConnectionDataPtr conn, char* msg, bool&) { return onConnectionDataOut(conn, msg); });
+
+	Hooks::UI::onChatCommand([this](HubDataPtr hub, CommandDataPtr command, bool&) { return onHubEnter(hub, command); });
 
 	/// @todo let the user configure which files to auto-load
 	auto file = Util::fromUtf8(Config::getConfig("ScriptPath")) + "startup.lua";
@@ -151,20 +139,60 @@
 
 	// This ensures that FormatChatText is only called when present...
 	if(CheckFunction("dcpp", "FormatChatHTML")) {
-		events[HOOK_UI_CHAT_DISPLAY] = hooks->bind_hook(HOOK_UI_CHAT_DISPLAY, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* bBreak) {
-			return instance->onFormatChat(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<StringDataPtr>(pData), bBreak); }, nullptr);
+		Hooks::UI::onChatDisplay([this](UserDataPtr user, StringDataPtr str, bool& bBreak) { return onFormatChat(user, str, bBreak); });
 	}
+
+	return true;
 }
 
 void Plugin::setTimer(bool bState) {
-	auto i = events.find(HOOK_TIMER_SECOND);
-	if(bState && i == events.end()) {
-		events[HOOK_TIMER_SECOND] = hooks->bind_hook(HOOK_TIMER_SECOND, [](dcptr_t, dcptr_t, dcptr_t, Bool*) {
-			return instance->onTimer(); }, nullptr);
-	} else if(i != events.end()) {
-		hooks->release_hook(i->second);
-		i->second = nullptr;
-	}
+	static bool timerHookAdded = false;
+	if(bState && !timerHookAdded) {
+		Hooks::Timer::onSecond([this](uint64_t, bool&) { return onTimer(); });
+		timerHookAdded = true;
+	} else if(timerHookAdded) {
+		Hooks::remove(HOOK_TIMER_SECOND);
+		timerHookAdded = false;
+	}
+}
+
+HubDataPtr Plugin::createHub(const char* url, const char* nick, const char* password) {
+	auto hHub = Hubs::handle()->add_hub(url, nick, password);
+	if(!hHub) hubs.insert(hHub);
+	return hHub;
+}
+
+void Plugin::destroyHub(HubDataPtr hHub) {
+	auto i = hubs.find(hHub);
+	if(i != hubs.end()) {
+		Hubs::handle()->remove_hub(*i);
+		Hubs::handle()->release(*i);
+		hubs.erase(i);
+	}
+}
+
+void Plugin::sendHubCommand(HubDataPtr hHub, const string& cmd) {
+	if(hHub)
+		Hubs::handle()->send_protocol_cmd(hHub, cmd.c_str());
+}
+
+void Plugin::injectHubCommand(HubDataPtr hHub, const string& cmd) {
+	if(hHub)
+		Hubs::handle()->emulate_protocol_cmd(hHub, cmd.c_str());
+}
+
+void Plugin::sendUdpPacket(const char* ip, uint32_t port, const string& data) {
+	Connections::handle()->send_udp_data(ip, port, reinterpret_cast<dcptr_t>(const_cast<char*>(data.c_str())), data.size());
+}
+
+void Plugin::sendClientCommand(ConnectionDataPtr hConn, const char* cmd) {
+	if(hConn)
+		Connections::handle()->send_protocol_cmd(hConn, cmd);
+}
+
+void Plugin::dropClientConnection(ConnectionDataPtr hConn, bool graceless) {
+	if(hConn)
+		Connections::handle()->terminate_conn(hConn, graceless ? True : False);
 }
 
 namespace { string formatBytes(double val) {
@@ -177,7 +205,7 @@
 	return buf;
 } }
 
-Bool Plugin::onHubEnter(HubDataPtr hHub, CommandDataPtr cmd) {
+bool Plugin::onHubEnter(HubDataPtr hHub, CommandDataPtr cmd) {
 	if(stricmp(cmd->command, "help") == 0) {
 		if(stricmp(cmd->params, "plugins") == 0) {
 			const char* help =
@@ -188,76 +216,76 @@
 				"\t /luadebug \t\t\t Toggle non-fatal error messages (default: off)\n"
 				"\t /formatchat \t\t\t Toggle Lua chat formatting hook (default: on, if available)\n";
 
-			hub->local_message(hHub, help, MSG_SYSTEM);
-			return True;
+			Hubs::handle()->local_message(hHub, help, MSG_SYSTEM);
+			return true;
 		}
 	} else if(stricmp(cmd->command, "lua") == 0) {
 		if(strlen(cmd->params) != 0) {
 			ScriptInstance::EvaluateChunk(cmd->params);
 		} else {
-			hub->local_message(hHub, "You must supply a parameter!", MSG_SYSTEM);
+			Hubs::handle()->local_message(hHub, "You must supply a parameter!", MSG_SYSTEM);
 		}
-		return True;
+		return true;
 	} else if(stricmp(cmd->command, "luafile") == 0) {
 		if(strlen(cmd->params) > 4) {
 			ScriptInstance::EvaluateFile(cmd->params);
 		} else {
-			hub->local_message(hHub, "You must supply a valid parameter!", MSG_SYSTEM);
+			Hubs::handle()->local_message(hHub, "You must supply a valid parameter!", MSG_SYSTEM);
 		}
-		return True;
+		return true;
 	} else if(stricmp(cmd->command, "meminfo") == 0 || stricmp(cmd->command, "luamem") == 0) {
 		// Run GC and get LUA memory usage
 		lua_gc(L, LUA_GCCOLLECT, 0);
 		double mem = lua_gc(L, LUA_GCCOUNT, 0);
 		auto stats = "Scripts (" LUA_DIST ") are using " + formatBytes(mem) + " of system memory";
 
-		hub->local_message(hHub, stats.c_str(), MSG_SYSTEM);
-		return True;
+		Hubs::handle()->local_message(hHub, stats.c_str(), MSG_SYSTEM);
+		return true;
 	} else if(stricmp(cmd->command, "luadebug") == 0) {
 		bool state = Config::getBoolConfig("LuaDebug");
 		const char* status = (state ? "Additional error messages disabled" : "Additional error messages enabled");
 
 		Config::setConfig("LuaDebug", state);
-		hub->local_message(hHub, status, MSG_SYSTEM);
-		return True;
+		Hubs::handle()->local_message(hHub, status, MSG_SYSTEM);
+		return true;
 	} else if(stricmp(cmd->command, "formatchat") == 0) {
 		bool state = Config::getBoolConfig("FormatChat");
 		const char* status = (state ? "Lua chat formatting disabled" : "Lua chat formatting enabled");
 
 		Config::setConfig("FormatChat", state);
-		hub->local_message(hHub, status, MSG_SYSTEM);
-		return True;
+		Hubs::handle()->local_message(hHub, status, MSG_SYSTEM);
+		return true;
 	}
 
 	// This stupidity is because of the API
-	return onOwnChatOut(hHub, string("/" + string(cmd->command) + " " + string(cmd->params)).c_str());
+	return onOwnChatOut(hHub, const_cast<char*>(string("/" + string(cmd->command) + " " + string(cmd->params)).c_str()));
 }
 
-Bool Plugin::onOwnChatOut(HubDataPtr hHub, const char* message) {
+bool Plugin::onOwnChatOut(HubDataPtr hHub, char* message) {
 	Lock l(cs);
-	return MakeCall("dcpp", "OnCommandEnter", 1, hHub, string(message)) ? GetLuaBool() : False;
+	return MakeCall("dcpp", "OnCommandEnter", 1, hHub, string(message)) ? static_cast<bool>(GetLuaBool()) : false;
 }
 
-Bool Plugin::onHubConnected(HubDataPtr hHub) {
+bool Plugin::onHubConnected(HubDataPtr hHub) {
 	MakeCall(GetHubType(hHub), "OnHubAdded", 0, hHub);
 
-	return False;
+	return false;
 }
 
-Bool Plugin::onHubDisconnected(HubDataPtr hHub) {
+bool Plugin::onHubDisconnected(HubDataPtr hHub) {
 	// fixme: DC++ may trigger this incorrectly (for hubs where OnHubAdded was never invoked), if socket creation fails...
 	MakeCall(GetHubType(hHub), "OnHubRemoved", 0, hHub);
 	removeChatCache(hHub);
 
-	return False;
+	return false;
 }
 
-Bool Plugin::onHubDataIn(HubDataPtr hHub, const char* message) {
+bool Plugin::onHubDataIn(HubDataPtr hHub, char* message) {
 	Lock l(cs);
-	return MakeCall(GetHubType(hHub), "DataArrival", 1, hHub, string(message)) ? GetLuaBool() : False;
+	return MakeCall(GetHubType(hHub), "DataArrival", 1, hHub, string(message)) ? static_cast<bool>(GetLuaBool()) : false;
 }
 
-Bool Plugin::onHubDataOut(HubDataPtr hHub, const char* message, Bool* bBreak) {
+bool Plugin::onHubDataOut(HubDataPtr hHub, char* message, bool& bBreak) {
 	string sText = message;
 	if(sText.find("LuaExec") != string::npos) {
 		string delim = (hHub->protocol == PROTOCOL_ADC) ? "\n" : "|";
@@ -273,27 +301,27 @@
 			j = ++i;
 		}
 		if(out.length() > 1)
-			hub->send_protocol_cmd(hHub, out.c_str());
+			Hubs::handle()->send_protocol_cmd(hHub, out.c_str());
 
 		// We don't need to send this to other plugins
-		*bBreak = True;
-		return True;
+		bBreak = true;
+		return true;
 	}
 
-	return False;
-}
-
-Bool Plugin::onConnectionDataIn(ConnectionDataPtr hConn, const char* message) {
-	Lock l(cs);
-	return MakeCall("dcpp", "UserDataIn", 1, hConn, string(message)) ? GetLuaBool() : False;
-}
-
-Bool Plugin::onConnectionDataOut(ConnectionDataPtr hConn, const char* message) {
-	Lock l(cs);
-	return MakeCall("dcpp", "UserDataOut", 1, hConn, string(message)) ? GetLuaBool() : False;
-}
-
-Bool Plugin::onFormatChat(UserDataPtr hUser, StringDataPtr line, Bool* bBreak) {
+	return false;
+}
+
+bool Plugin::onConnectionDataIn(ConnectionDataPtr hConn, char* message) {
+	Lock l(cs);
+	return MakeCall("dcpp", "UserDataIn", 1, hConn, string(message)) ? static_cast<bool>(GetLuaBool()) : false;
+}
+
+bool Plugin::onConnectionDataOut(ConnectionDataPtr hConn, char* message) {
+	Lock l(cs);
+	return MakeCall("dcpp", "UserDataOut", 1, hConn, string(message)) ? static_cast<bool>(GetLuaBool()) : false;
+}
+
+bool Plugin::onFormatChat(UserDataPtr hUser, StringDataPtr line, bool& bBreak) {
 	Lock l(cs);
 	if(!hUser || !Config::getBoolConfig("FormatChat") || !MakeCall("dcpp", "FormatChatHTML", 1, hUser, string(line->in)))
 		return False;
@@ -308,14 +336,15 @@
 
 	lua_settop(L, 0);
 
-	if(line->out != NULL) {
+	if(line->out) {
 		// We don't send this to other plugins (users can control which formatting applies via plugin order)
-		*bBreak = True;
-		return True;
-	} else return False;
+		bBreak = true;
+		return true;
+	}
+	return false;
 }
 
-Bool Plugin::onTimer() {
+bool Plugin::onTimer() {
 	MakeCall("dcpp", "OnTimer", 0, 0);
-	return False;
+	return false;
 }

=== modified file 'plugins/Script/Plugin.h'
--- plugins/Script/Plugin.h	2012-11-05 20:39:11 +0000
+++ plugins/Script/Plugin.h	2012-11-11 17:43:20 +0000
@@ -35,45 +35,16 @@
 
 	void setTimer(bool bState);
 
-	HubDataPtr createHub(const char* url, const char* nick, const char* password) {
-		auto hHub = hub->add_hub(url, nick, password);
-		if(!hHub) hubs.insert(hHub);
-		return hHub;
-	}
-
-	void destroyHub(HubDataPtr hHub) {
-		auto i = hubs.find(hHub);
-		if(i != hubs.end()) {
-			hub->remove_hub(*i);
-			hub->release(*i);
-			hubs.erase(i);
-		}
-	}
-
-	void sendHubCommand(HubDataPtr hHub, const string& cmd) {
-		if(hHub)
-			hub->send_protocol_cmd(hHub, cmd.c_str());
-	}
-
-	void injectHubCommand(HubDataPtr hHub, const string& cmd) {
-		if(hHub)
-			hub->emulate_protocol_cmd(hHub, cmd.c_str());
-	}
+	HubDataPtr createHub(const char* url, const char* nick, const char* password);
+	void destroyHub(HubDataPtr hHub);
+
+	void sendHubCommand(HubDataPtr hHub, const string& cmd);
+	void injectHubCommand(HubDataPtr hHub, const string& cmd);
 
 	// Accessors (c<->c connections)
-	void sendUdpPacket(const char* ip, uint32_t port, const string& data) {
-		connection->send_udp_data(ip, port, (dcptr_t)data.c_str(), data.size());
-	}
-
-	void sendClientCommand(ConnectionDataPtr hConn, const char* cmd) {
-		if(hConn)
-			connection->send_protocol_cmd(hConn, cmd);
-	}
-
-	void dropClientConnection(ConnectionDataPtr hConn, bool graceless) {
-		if(hConn)
-			connection->terminate_conn(hConn, graceless ? True : False);
-	}
+	void sendUdpPacket(const char* ip, uint32_t port, const string& data);
+	void sendClientCommand(ConnectionDataPtr hConn, const char* cmd);
+	void dropClientConnection(ConnectionDataPtr hConn, bool graceless);
 
 	static Plugin* getInstance() { return instance; }
 
@@ -81,17 +52,17 @@
 	Plugin();
 	~Plugin();
 
-	void onLoad(DCCorePtr core, bool install, Bool& loadRes);
-	Bool onHubEnter(HubDataPtr hHub, CommandDataPtr cmd);
-	Bool onOwnChatOut(HubDataPtr hHub, const char* message);
-	Bool onHubConnected(HubDataPtr hHub);
-	Bool onHubDisconnected(HubDataPtr hHub);
-	Bool onHubDataIn(HubDataPtr hHub, const char* message);
-	Bool onHubDataOut(HubDataPtr hHub, const char* message, Bool* bBreak);
-	Bool onConnectionDataIn(ConnectionDataPtr hConn, const char* message);
-	Bool onConnectionDataOut(ConnectionDataPtr hConn, const char* message);
-	Bool onFormatChat(UserDataPtr hUser, StringDataPtr line, Bool* bBreak);
-	Bool onTimer();
+	bool onLoad(DCCorePtr core, bool install);
+	bool onHubEnter(HubDataPtr hHub, CommandDataPtr cmd);
+	bool onOwnChatOut(HubDataPtr hHub, char* message);
+	bool onHubConnected(HubDataPtr hHub);
+	bool onHubDisconnected(HubDataPtr hHub);
+	bool onHubDataIn(HubDataPtr hHub, char* message);
+	bool onHubDataOut(HubDataPtr hHub, char* message, bool& bBreak);
+	bool onConnectionDataIn(ConnectionDataPtr hConn, char* message);
+	bool onConnectionDataOut(ConnectionDataPtr hConn, char* message);
+	bool onFormatChat(UserDataPtr hUser, StringDataPtr line, bool& bBreak);
+	bool onTimer();
 
 	void removeChatCache(const HubDataPtr hub) {
 		auto j = chatCache.find(hub->url);
@@ -99,17 +70,9 @@
 			chatCache.erase(j);
 	}
 
-	map<string, subsHandle> events;
 	map<string, string> chatCache;
 	set<HubDataPtr> hubs;
 
-	DCHooksPtr hooks;
-
-	DCHubPtr hub;
-	DCConnectionPtr connection;
-
-	/** @todo switch to dcpp::Singleton when <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494>
-	is fixed */
 	static Plugin* instance;
 };
 

=== modified file 'plugins/Script/pluginsdk.cpp'
--- plugins/Script/pluginsdk.cpp	2012-11-04 19:15:24 +0000
+++ plugins/Script/pluginsdk.cpp	2012-11-11 17:43:20 +0000
@@ -3,7 +3,10 @@
 
 #include "version.h"
 
+#include <pluginsdk/Config.cpp>
+#include <pluginsdk/Connections.cpp>
 #include <pluginsdk/Core.cpp>
-#include <pluginsdk/Config.cpp>
+#include <pluginsdk/Hooks.cpp>
+#include <pluginsdk/Hubs.cpp>
 #include <pluginsdk/Logger.cpp>
 #include <pluginsdk/Util.cpp>

=== modified file 'plugins/Test/pluginsdk.cpp'
--- plugins/Test/pluginsdk.cpp	2012-11-11 17:07:47 +0000
+++ plugins/Test/pluginsdk.cpp	2012-11-11 17:43:20 +0000
@@ -3,8 +3,8 @@
 
 #include "version.h"
 
+#include <pluginsdk/Config.cpp>
 #include <pluginsdk/Core.cpp>
-#include <pluginsdk/Config.cpp>
 #include <pluginsdk/Hooks.cpp>
 #include <pluginsdk/Logger.cpp>
 #include <pluginsdk/Tagger.cpp>

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.cpp'
--- pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-11 16:28:14 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-11 17:43:20 +0000
@@ -144,6 +144,14 @@
 	events.clear();
 }
 
+void Hooks::remove(const char* id) {
+	auto i = events.find(id);
+	if(i != events.end()) {
+		hooks->release_hook(i->second.first);
+		events.erase(i);
+	}
+}
+
 void Hooks::addEvent(const char* id, Callback f) {
 	// insert first to construct map keys etc; then create the hook, using the map key as pCommon.
 	auto it = events.insert(make_pair(id, make_pair(nullptr, f))).first;

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.h'
--- pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-11 16:28:14 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-11 17:43:20 +0000
@@ -98,6 +98,7 @@
 
 	static bool empty();
 	static void clear();
+	static void remove(const char* id);
 
 private:
 	typedef function<bool (dcptr_t, dcptr_t, bool&)> Callback;