← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3128: plugins: continue the Hooks class; split the /command hook in 2

 

------------------------------------------------------------
revno: 3128
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sun 2012-11-11 16:12:15 +0100
message:
  plugins: continue the Hooks class; split the /command hook in 2
modified:
  dcpp/PluginApiImpl.cpp
  dcpp/PluginManager.cpp
  plugins/Dev/Plugin.cpp
  plugins/Dev/Plugin.h
  plugins/Example/Plugin.c
  plugins/Script/Plugin.cpp
  pluginsdk/PluginDefs.h
  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 'dcpp/PluginApiImpl.cpp'
--- dcpp/PluginApiImpl.cpp	2012-11-01 22:13:45 +0000
+++ dcpp/PluginApiImpl.cpp	2012-11-11 15:12:15 +0000
@@ -42,7 +42,7 @@
 
 namespace dcpp {
 
-#define IMPL_HOOKS_COUNT 20
+#define IMPL_HOOKS_COUNT 21
 
 static const char* hookGuids[IMPL_HOOKS_COUNT] = {
 	HOOK_CHAT_IN,
@@ -61,15 +61,16 @@
 	HOOK_NETWORK_CONN_IN,
 	HOOK_NETWORK_CONN_OUT,
 
-	HOOK_QUEUE_ADD,
-	HOOK_QUEUE_MOVE,
-	HOOK_QUEUE_REMOVE,
+	HOOK_QUEUE_ADDED,
+	HOOK_QUEUE_MOVED,
+	HOOK_QUEUE_REMOVED,
 	HOOK_QUEUE_FINISHED,
 
 	HOOK_UI_CREATED,
 	HOOK_UI_CHAT_TAGS,
 	HOOK_UI_CHAT_DISPLAY,
-	HOOK_UI_PROCESS_CHAT_CMD		
+	HOOK_UI_CHAT_COMMAND,
+	HOOK_UI_CHAT_COMMAND_PM
 };
 
 static const char* hostName = APPNAME;

=== modified file 'dcpp/PluginManager.cpp'
--- dcpp/PluginManager.cpp	2012-10-06 03:20:43 +0000
+++ dcpp/PluginManager.cpp	2012-11-11 15:12:15 +0000
@@ -240,8 +240,8 @@
 		cmd = line.substr(1);
 	}
 
-	CommandData data = { cmd.c_str(), param.c_str(), False };
-	return runHook(HOOK_UI_PROCESS_CHAT_CMD, client, &data);
+	CommandData data = { cmd.c_str(), param.c_str() };
+	return runHook(HOOK_UI_CHAT_COMMAND, client, &data);
 }
 
 bool PluginManager::onChatCommandPM(const HintedUser& user, const string& line) {
@@ -260,8 +260,8 @@
 			cmd = line.substr(1);
 		}
 
-		CommandData data = { cmd.c_str(), param.c_str(), True };
-		res = runHook(HOOK_UI_PROCESS_CHAT_CMD, ou, &data);
+		CommandData data = { cmd.c_str(), param.c_str() };
+		res = runHook(HOOK_UI_CHAT_COMMAND_PM, ou, &data);
 	}
 
 	return res;
@@ -440,15 +440,15 @@
 }
 
 void PluginManager::on(QueueManagerListener::Added, QueueItem* qi) noexcept {
-	runHook(HOOK_QUEUE_ADD, qi);
+	runHook(HOOK_QUEUE_ADDED, qi);
 }
 
 void PluginManager::on(QueueManagerListener::Moved, QueueItem* qi, const string& /*aSource*/) noexcept {
-	runHook(HOOK_QUEUE_MOVE, qi);
+	runHook(HOOK_QUEUE_MOVED, qi);
 }
 
 void PluginManager::on(QueueManagerListener::Removed, QueueItem* qi) noexcept {
-	runHook(HOOK_QUEUE_REMOVE, qi);
+	runHook(HOOK_QUEUE_REMOVED, qi);
 }
 
 void PluginManager::on(QueueManagerListener::Finished, QueueItem* qi, const string& /*dir*/, int64_t /*speed*/) noexcept {

=== modified file 'plugins/Dev/Plugin.cpp'
--- plugins/Dev/Plugin.cpp	2012-11-10 17:16:16 +0000
+++ plugins/Dev/Plugin.cpp	2012-11-11 15:12:15 +0000
@@ -33,7 +33,7 @@
 
 Plugin* Plugin::instance = nullptr;
 
-Plugin::Plugin() : commandName(PLUGIN_NAME ": enable") {
+Plugin::Plugin() {
 }
 
 Plugin::~Plugin() {
@@ -71,26 +71,15 @@
 }
 
 void Plugin::dlgClosed() {
-	auto oldCommand = instance->commandName;
 	instance->close();
-
-	instance->ui->remove_command(oldCommand.c_str());
-	instance->ui->add_command(instance->commandName.c_str(), [] { instance->onSwitched(); });
 }
 
 void Plugin::addHooks() {
-	Hooks::onHubDataIn([this](HubDataPtr hHub, const char* message, bool&) { return onHubDataIn(hHub, message); });
-	/*
-	events[HOOK_NETWORK_HUB_OUT] = hooks->bind_hook(HOOK_NETWORK_HUB_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		return instance->onHubDataOut(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, 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_PROCESS_CHAT_CMD] = hooks->bind_hook(HOOK_UI_PROCESS_CHAT_CMD, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
-		auto cmd = reinterpret_cast<CommandDataPtr>(pData);
-		if(cmd->isPrivate) { return False; }
-		return instance->onChatCommand(reinterpret_cast<HubDataPtr>(pObject), cmd); }, nullptr);*/
+	Hooks::Network::onHubDataIn([this](HubDataPtr hHub, char* message, bool&) { return onHubDataIn(hHub, message); });
+	Hooks::Network::onHubDataOut([this](HubDataPtr hHub, char* message, bool&) { return onHubDataOut(hHub, message); });
+	Hooks::Network::onClientDataIn([this](ConnectionDataPtr hConn, char* message, bool&) { return onClientDataIn(hConn, message); });
+	Hooks::Network::onClientDataOut([this](ConnectionDataPtr hConn, char* message, bool&) { return onClientDataOut(hConn, message); });
+	Hooks::UI::onChatCommand([this](HubDataPtr hHub, CommandDataPtr cmd, bool&) { return onChatCommand(hHub, cmd); });
 }
 
 void Plugin::clearHooks() {
@@ -101,14 +90,20 @@
 	dialog.create();
 	addHooks();
 	Config::setConfig("Enabled", true);
-	commandName = PLUGIN_NAME ": disable";
+	refreshSwitchCommand();
 }
 
 void Plugin::close() {
 	Config::setConfig("Enabled", false);
 	clearHooks();
 	dialog.close();
-	commandName = PLUGIN_NAME ": enable";
+	refreshSwitchCommand();
+}
+
+void Plugin::refreshSwitchCommand() {
+	ui->remove_command(commandName.c_str());
+	commandName = Hooks::empty() ? PLUGIN_NAME ": enable" : PLUGIN_NAME ": disable";
+	ui->add_command(commandName.c_str(), [] { instance->onSwitched(); });
 }
 
 void Plugin::onLoad(DCCorePtr core, bool install, Bool& loadRes) {
@@ -129,44 +124,40 @@
 
 	if(Config::getBoolConfig("Enabled")) {
 		start();
+	} else {
+		refreshSwitchCommand();
 	}
-
-	ui->add_command(commandName.c_str(), [] { instance->onSwitched(); });
 }
 
 void Plugin::onSwitched() {
-	auto oldCommand = commandName;
 	if(Hooks::empty()) {
 		start();
 	} else {
 		close();
 	}
-
-	ui->remove_command(oldCommand.c_str());
-	ui->add_command(commandName.c_str(), [] { instance->onSwitched(); });
 }
 
-Bool Plugin::onHubDataIn(HubDataPtr hHub, const char* message) {
+bool Plugin::onHubDataIn(HubDataPtr hHub, char* message) {
 	dialog.write(true, false, hHub->ip, hHub->port, "Hub " + string(hHub->url), message);
-	return False;
+	return false;
 }
 
-Bool Plugin::onHubDataOut(HubDataPtr hHub, const char* message) {
+bool Plugin::onHubDataOut(HubDataPtr hHub, char* message) {
 	dialog.write(true, true, hHub->ip, hHub->port, "Hub " + string(hHub->url), message);
-	return False;
+	return false;
 }
 
-Bool Plugin::onConnectionDataIn(ConnectionDataPtr hConn, const char* message) {
+bool Plugin::onClientDataIn(ConnectionDataPtr hConn, char* message) {
 	dialog.write(false, false, hConn->ip, hConn->port, "User" /** @todo get user's nick */, message);
-	return False;
+	return false;
 }
 
-Bool Plugin::onConnectionDataOut(ConnectionDataPtr hConn, const char* message) {
+bool Plugin::onClientDataOut(ConnectionDataPtr hConn, char* message) {
 	dialog.write(false, true, hConn->ip, hConn->port, "User" /** @todo get user's nick */, message);
-	return False;
+	return false;
 }
 
-Bool Plugin::onChatCommand(HubDataPtr hub, CommandDataPtr cmd) {
+bool Plugin::onChatCommand(HubDataPtr hub, CommandDataPtr cmd) {
 	if(stricmp(cmd->command, "help") == 0) {
 		hubs->local_message(hub, "/raw <message>", MSG_SYSTEM);
 
@@ -178,5 +169,5 @@
 		}
 	}
 
-	return False;
+	return false;
 }

=== modified file 'plugins/Dev/Plugin.h'
--- plugins/Dev/Plugin.h	2012-11-10 17:16:16 +0000
+++ plugins/Dev/Plugin.h	2012-11-11 15:12:15 +0000
@@ -40,13 +40,15 @@
 	void start();
 	void close();
 
+	void refreshSwitchCommand();
+
 	void onLoad(DCCorePtr core, bool install, Bool& loadRes);
 	void onSwitched();
-	Bool onHubDataIn(HubDataPtr hHub, const char* message);
-	Bool onHubDataOut(HubDataPtr hHub, const char* message);
-	Bool onConnectionDataIn(ConnectionDataPtr hConn, const char* message);
-	Bool onConnectionDataOut(ConnectionDataPtr hConn, const char* message);
-	Bool onChatCommand(HubDataPtr hub, CommandDataPtr cmd);
+	bool onHubDataIn(HubDataPtr hHub, char* message);
+	bool onHubDataOut(HubDataPtr hHub, char* message);
+	bool onClientDataIn(ConnectionDataPtr hConn, char* message);
+	bool onClientDataOut(ConnectionDataPtr hConn, char* message);
+	bool onChatCommand(HubDataPtr hub, CommandDataPtr cmd);
 
 	DCHubPtr hubs;
 	DCUIPtr ui;

=== modified file 'plugins/Example/Plugin.c'
--- plugins/Example/Plugin.c	2012-11-10 03:44:55 +0000
+++ plugins/Example/Plugin.c	2012-11-11 15:12:15 +0000
@@ -47,7 +47,7 @@
 #define HOOKS_SUBSCRIBED 4
 
 const char* hookGuids[HOOKS_SUBSCRIBED] = {
-	HOOK_UI_PROCESS_CHAT_CMD,
+	HOOK_UI_CHAT_COMMAND,
 	HOOK_HUB_ONLINE,
 	HOOK_TIMER_SECOND,
 	HOOK_UI_CHAT_TAGS
@@ -105,9 +105,6 @@
 	HubDataPtr hHub = (HubDataPtr)pObject;
 	CommandDataPtr cmd = (CommandDataPtr)pData;
 
-	if(cmd->isPrivate)
-		return False;
-
 	if(stricmp(cmd->command, "help") == 0 && stricmp(cmd->params, "plugins") == 0) {
 		const char* help =
 			"\t\t\t Help: " PLUGIN_NAME " \n"

=== modified file 'plugins/Script/Plugin.cpp'
--- plugins/Script/Plugin.cpp	2012-11-08 12:41:54 +0000
+++ plugins/Script/Plugin.cpp	2012-11-11 15:12:15 +0000
@@ -141,7 +141,7 @@
 	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_PROCESS_CHAT_CMD] = hooks->bind_hook(HOOK_UI_PROCESS_CHAT_CMD, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
+	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);
 
 	/// @todo let the user configure which files to auto-load
@@ -178,9 +178,6 @@
 } }
 
 Bool Plugin::onHubEnter(HubDataPtr hHub, CommandDataPtr cmd) {
-	if(cmd->isPrivate)
-		return False;
-
 	if(stricmp(cmd->command, "help") == 0) {
 		if(stricmp(cmd->params, "plugins") == 0) {
 			const char* help =

=== modified file 'pluginsdk/PluginDefs.h'
--- pluginsdk/PluginDefs.h	2012-11-04 19:15:24 +0000
+++ pluginsdk/PluginDefs.h	2012-11-11 15:12:15 +0000
@@ -24,7 +24,7 @@
 #endif
 
 /* Version of the plugin api (must change if old plugins simply can't be seen as viably working) */
-#define DCAPI_CORE_VER				5
+#define DCAPI_CORE_VER				6
 
 #ifdef _WIN32
 # define DCAPI __stdcall
@@ -75,33 +75,34 @@
 #define DCINTF_DCPP_UI_VER			1
 
 /* Hook GUID's for Hooks (events) system */
-#define HOOK_CHAT_IN				"dcpp.chat.onIncomingChat"	/* Incoming chat from hub (obj: HubData) */
-#define HOOK_CHAT_OUT				"dcpp.chat.onOutgoingChat"	/* Outgoing chat (obj: HubData) */
-#define HOOK_CHAT_PM_IN				"dcpp.chat.onIncomingPM"	/* Incoming private message (obj: UserData) */
-#define HOOK_CHAT_PM_OUT			"dcpp.chat.onOutgoingPM"	/* Outgoing private message (obj: UserData) */
-
-#define HOOK_TIMER_SECOND			"dcpp.timer.onSecond"		/* Timer event fired once per second (data: tick value) */
-#define HOOK_TIMER_MINUTE			"dcpp.timer.onMinute"		/* Timer event fired once per minute (data: tick value) */
-
-#define HOOK_HUB_ONLINE				"dcpp.hubs.onOnline"		/* (New) hub has just gone online (obj: HubData) */
-#define HOOK_HUB_OFFLINE			"dcpp.hubs.onOffline"		/* Hub has just gone offline (obj: HubData) */
-#define HOOK_USER_ONLINE			"dcpp.users.onOnline"		/* User is online (obj: UserData) */
-#define HOOK_USER_OFFLINE			"dcpp.users.onOffline"		/* User is offline (obj: UserData) */
+#define HOOK_CHAT_IN				"dcpp.chat.onIncomingChat"		/* Incoming chat from hub (obj: HubData) */
+#define HOOK_CHAT_OUT				"dcpp.chat.onOutgoingChat"		/* Outgoing chat (obj: HubData) */
+#define HOOK_CHAT_PM_IN				"dcpp.chat.onIncomingPM"		/* Incoming private message (obj: UserData) */
+#define HOOK_CHAT_PM_OUT			"dcpp.chat.onOutgoingPM"		/* Outgoing private message (obj: UserData) */
+
+#define HOOK_TIMER_SECOND			"dcpp.timer.onSecond"			/* Timer event fired once per second (data: tick value) */
+#define HOOK_TIMER_MINUTE			"dcpp.timer.onMinute"			/* Timer event fired once per minute (data: tick value) */
+
+#define HOOK_HUB_ONLINE				"dcpp.hubs.onOnline"			/* (New) hub has just gone online (obj: HubData) */
+#define HOOK_HUB_OFFLINE			"dcpp.hubs.onOffline"			/* Hub has just gone offline (obj: HubData) */
+#define HOOK_USER_ONLINE			"dcpp.users.onOnline"			/* User is online (obj: UserData) */
+#define HOOK_USER_OFFLINE			"dcpp.users.onOffline"			/* User is offline (obj: UserData) */
 
 #define HOOK_NETWORK_HUB_IN			"dcpp.network.onHubDataIn"		/* Incoming protocol messages from hub (obj: HubData) */
 #define HOOK_NETWORK_HUB_OUT		"dcpp.network.onHubDataOut"		/* Outgoing protocol message to hub (obj: HubData) */
 #define HOOK_NETWORK_CONN_IN		"dcpp.network.onClientDataIn"	/* Incoming client<->client protocol message (obj: ConnectionData) */
 #define HOOK_NETWORK_CONN_OUT		"dcpp.network.onClientDataOut"	/* Outgoing client<->client protocol message (obj: ConnectionData) */
 
-#define HOOK_QUEUE_ADD				"dcpp.queue.onAdd"			/* (New) item has been added to download queue (obj: QueueData) */
-#define HOOK_QUEUE_MOVE				"dcpp.queue.onMove"			/* Download queue item has been moved to new location (obj: QueueData) */
-#define HOOK_QUEUE_REMOVE			"dcpp.queue.onRemove"		/* Item has just been removed from download queue (obj: QueueData) */
-#define HOOK_QUEUE_FINISHED			"dcpp.queue.onFinished"		/* Item has just finished downloading (obj: QueueData) */
+#define HOOK_QUEUE_ADDED			"dcpp.queue.onAdded"			/* (New) item has been added to download queue (obj: QueueData) */
+#define HOOK_QUEUE_MOVED			"dcpp.queue.onMoved"			/* Download queue item has been moved to new location (obj: QueueData) */
+#define HOOK_QUEUE_REMOVED			"dcpp.queue.onRemoved"			/* Item has just been removed from download queue (obj: QueueData) */
+#define HOOK_QUEUE_FINISHED			"dcpp.queue.onFinished"			/* Item has just finished downloading (obj: QueueData) */
 
 #define HOOK_UI_CREATED				"dcpp.ui.onCreated"				/* Host application UI has been created (obj: if any, impl. dependant) */
 #define HOOK_UI_CHAT_TAGS			"dcpp.ui.onChatTags"			/* Chat message tags before tag merging (obj: UserData; data: TagData) */
 #define HOOK_UI_CHAT_DISPLAY		"dcpp.ui.onChatDisplay"			/* Chat messages before they are displayed in chat (obj: UserData; data: StringData) */
-#define HOOK_UI_PROCESS_CHAT_CMD	"dcpp.ui.onProcessCmd"			/* Client side commands in chat (obj: HubData/UserData; data: CommandData) */
+#define HOOK_UI_CHAT_COMMAND		"dcpp.ui.onChatCommand"			/* Client side commands in hub chat (obj: HubData; data: CommandData) */
+#define HOOK_UI_CHAT_COMMAND_PM		"dcpp.ui.onChatCommandPM"		/* Client side commands in private chat (obj: UserData; data: CommandData) */
 
 /* Main hook events (returned by pluginInit) */
 typedef enum tagPluginState {
@@ -200,7 +201,6 @@
 typedef struct tagCommandData {
 	const char* command;										/* Command name */
 	const char* params;											/* Command parameters passed */
-	Bool isPrivate;												/* Used in a private context (private messages) */
 } CommandData, *CommandDataPtr;
 
 /* Users */

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.cpp'
--- pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-10 17:16:16 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.cpp	2012-11-11 15:12:15 +0000
@@ -16,7 +16,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 
-/* Helpers around the DCCore interface. */
+/* Helpers around the DCHooks interface. */
 
 #include "Hooks.h"
 
@@ -31,10 +31,104 @@
 }
 void Hooks::init(DCHooksPtr coreHooks) { hooks = coreHooks; }
 
-void Hooks::onHubDataIn(function<bool (HubDataPtr, char*, bool&)> f) {
+void Hooks::Chat::onIncomingChat(function<bool (HubDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_CHAT_IN, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+void Hooks::Chat::onOutgoingChat(function<bool (HubDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_CHAT_OUT, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+void Hooks::Chat::onIncomingPM(function<bool (UserDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_CHAT_PM_IN, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+void Hooks::Chat::onOutgoingPM(function<bool (UserDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_CHAT_PM_OUT, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+
+void Hooks::Timer::onSecond(function<bool (uint64_t, bool&)> f) {
+	addEvent(HOOK_TIMER_SECOND, [f](dcptr_t, dcptr_t pData, bool& bBreak) {
+		return f(*reinterpret_cast<uint64_t*>(pData), bBreak); });
+}
+void Hooks::Timer::onMinute(function<bool (uint64_t, bool&)> f) {
+	addEvent(HOOK_TIMER_MINUTE, [f](dcptr_t, dcptr_t pData, bool& bBreak) {
+		return f(*reinterpret_cast<uint64_t*>(pData), bBreak); });
+}
+
+void Hooks::Hubs::onOnline(function<bool (HubDataPtr, bool&)> f) {
+	addEvent(HOOK_HUB_ONLINE, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), bBreak); });
+}
+void Hooks::Hubs::onOffline(function<bool (HubDataPtr, bool&)> f) {
+	addEvent(HOOK_HUB_OFFLINE, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), bBreak); });
+}
+
+void Hooks::Users::onOnline(function<bool (UserDataPtr, bool&)> f) {
+	addEvent(HOOK_USER_ONLINE, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), bBreak); });
+}
+void Hooks::Users::onOffline(function<bool (UserDataPtr, bool&)> f) {
+	addEvent(HOOK_USER_OFFLINE, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), bBreak); });
+}
+
+void Hooks::Network::onHubDataIn(function<bool (HubDataPtr, char*, bool&)> f) {
 	addEvent(HOOK_NETWORK_HUB_IN, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
 		return f(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
 }
+void Hooks::Network::onHubDataOut(function<bool (HubDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_NETWORK_HUB_OUT, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+void Hooks::Network::onClientDataIn(function<bool (ConnectionDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_NETWORK_CONN_IN, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+void Hooks::Network::onClientDataOut(function<bool (ConnectionDataPtr, char*, bool&)> f) {
+	addEvent(HOOK_NETWORK_CONN_OUT, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); });
+}
+
+void Hooks::Queue::onAdded(function<bool (QueueDataPtr, bool&)> f) {
+	addEvent(HOOK_QUEUE_ADDED, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<QueueDataPtr>(pObject), bBreak); });
+}
+void Hooks::Queue::onMoved(function<bool (QueueDataPtr, bool&)> f) {
+	addEvent(HOOK_QUEUE_MOVED, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<QueueDataPtr>(pObject), bBreak); });
+}
+void Hooks::Queue::onRemoved(function<bool (QueueDataPtr, bool&)> f) {
+	addEvent(HOOK_QUEUE_REMOVED, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<QueueDataPtr>(pObject), bBreak); });
+}
+void Hooks::Queue::onFinished(function<bool (QueueDataPtr, bool&)> f) {
+	addEvent(HOOK_QUEUE_FINISHED, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(reinterpret_cast<QueueDataPtr>(pObject), bBreak); });
+}
+
+void Hooks::UI::onCreated(function<bool (dcptr_t, bool&)> f) {
+	addEvent(HOOK_UI_CREATED, [f](dcptr_t pObject, dcptr_t, bool& bBreak) {
+		return f(pObject, bBreak); });
+}
+void Hooks::UI::onChatTags(function<bool (UserDataPtr, TagDataPtr, bool&)> f) {
+	addEvent(HOOK_UI_CHAT_TAGS, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<TagDataPtr>(pData), bBreak); });
+}
+void Hooks::UI::onChatDisplay(function<bool (UserDataPtr, StringDataPtr, bool&)> f) {
+	addEvent(HOOK_UI_CHAT_DISPLAY, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<StringDataPtr>(pData), bBreak); });
+}
+void Hooks::UI::onChatCommand(function<bool (HubDataPtr, CommandDataPtr, bool&)> f) {
+	addEvent(HOOK_UI_CHAT_COMMAND, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<CommandDataPtr>(pData), bBreak); });
+}
+void Hooks::UI::onChatCommandPM(function<bool (UserDataPtr, CommandDataPtr, bool&)> f) {
+	addEvent(HOOK_UI_CHAT_COMMAND_PM, [f](dcptr_t pObject, dcptr_t pData, bool& bBreak) {
+		return f(reinterpret_cast<UserDataPtr>(pObject), reinterpret_cast<CommandDataPtr>(pData), bBreak); });
+}
 
 bool Hooks::empty() {
 	return events.empty();

=== modified file 'pluginsdk/cpp/pluginsdk/Hooks.h'
--- pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-10 17:16:16 +0000
+++ pluginsdk/cpp/pluginsdk/Hooks.h	2012-11-11 15:12:15 +0000
@@ -42,7 +42,56 @@
 	static bool init(DCCorePtr core);
 	static void init(DCHooksPtr coreHooks);
 
-	static void onHubDataIn(function<bool (HubDataPtr, char*, bool&)> f);
+	/* The following functions register events. See the Hooks section of PluginDefs.h to see a
+	description of each.
+	Callbacks return a bool to indicate whether they want to prevent the plugin host from doing any
+	further processing related to the event.
+	Callbacks are also given a "bool& bBreak" argument to indicate whether they want to prevent
+	other plugins from catching the event. */
+
+	struct Chat {
+		static void onIncomingChat(function<bool (HubDataPtr, char*, bool&)> f);
+		static void onOutgoingChat(function<bool (HubDataPtr, char*, bool&)> f);
+		static void onIncomingPM(function<bool (UserDataPtr, char*, bool&)> f);
+		static void onOutgoingPM(function<bool (UserDataPtr, char*, bool&)> f);
+	};
+
+	struct Timer {
+		static void onSecond(function<bool (uint64_t, bool&)> f);
+		static void onMinute(function<bool (uint64_t, bool&)> f);
+	};
+
+	struct Hubs {
+		static void onOnline(function<bool (HubDataPtr, bool&)> f);
+		static void onOffline(function<bool (HubDataPtr, bool&)> f);
+	};
+
+	struct Users {
+		static void onOnline(function<bool (UserDataPtr, bool&)> f);
+		static void onOffline(function<bool (UserDataPtr, bool&)> f);
+	};
+
+	struct Network {
+		static void onHubDataIn(function<bool (HubDataPtr, char*, bool&)> f);
+		static void onHubDataOut(function<bool (HubDataPtr, char*, bool&)> f);
+		static void onClientDataIn(function<bool (ConnectionDataPtr, char*, bool&)> f);
+		static void onClientDataOut(function<bool (ConnectionDataPtr, char*, bool&)> f);
+	};
+
+	struct Queue {
+		static void onAdded(function<bool (QueueDataPtr, bool&)> f);
+		static void onMoved(function<bool (QueueDataPtr, bool&)> f);
+		static void onRemoved(function<bool (QueueDataPtr, bool&)> f);
+		static void onFinished(function<bool (QueueDataPtr, bool&)> f);
+	};
+
+	struct UI {
+		static void onCreated(function<bool (dcptr_t, bool&)> f);
+		static void onChatTags(function<bool (UserDataPtr, TagDataPtr, bool&)> f);
+		static void onChatDisplay(function<bool (UserDataPtr, StringDataPtr, bool&)> f);
+		static void onChatCommand(function<bool (HubDataPtr, CommandDataPtr, bool&)> f);
+		static void onChatCommandPM(function<bool (UserDataPtr, CommandDataPtr, bool&)> f);
+	};
 
 	static bool empty();
 	static void clear();