summary refs log tree commit diff stats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/checksum/checksum.vcxproj2
-rw-r--r--plugins/dns/dns.vcxproj2
-rw-r--r--plugins/doat/doat.vcxproj2
-rw-r--r--plugins/exec/exec.vcxproj2
-rw-r--r--plugins/fishlim/fishlim.vcxproj2
-rw-r--r--plugins/hextray/hextray.vcxproj2
-rw-r--r--plugins/mpcinfo/mpcinfo.vcxproj2
-rw-r--r--plugins/perl/perl.vcxproj2
-rw-r--r--plugins/python/python.c423
-rw-r--r--plugins/python/python2.vcxproj2
-rw-r--r--plugins/python/python3.vcxproj2
-rw-r--r--plugins/sysinfo/sysinfo.vcxproj2
-rw-r--r--plugins/upd/upd.c80
-rw-r--r--plugins/upd/upd.vcxproj2
-rw-r--r--plugins/winamp/winamp.vcxproj2
15 files changed, 402 insertions, 127 deletions
diff --git a/plugins/checksum/checksum.vcxproj b/plugins/checksum/checksum.vcxproj
index 4090675c..ce75d68b 100644
--- a/plugins/checksum/checksum.vcxproj
+++ b/plugins/checksum/checksum.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;CHECKSUM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/dns/dns.vcxproj b/plugins/dns/dns.vcxproj
index 39e47f67..f34c7bc3 100644
--- a/plugins/dns/dns.vcxproj
+++ b/plugins/dns/dns.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DNS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DNS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/doat/doat.vcxproj b/plugins/doat/doat.vcxproj
index bb44030d..32ac7055 100644
--- a/plugins/doat/doat.vcxproj
+++ b/plugins/doat/doat.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -78,7 +77,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;DOAT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/exec/exec.vcxproj b/plugins/exec/exec.vcxproj
index f1710119..e789767f 100644
--- a/plugins/exec/exec.vcxproj
+++ b/plugins/exec/exec.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -78,7 +77,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;EXEC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/fishlim/fishlim.vcxproj b/plugins/fishlim/fishlim.vcxproj
index 3743057c..d21c21ad 100644
--- a/plugins/fishlim/fishlim.vcxproj
+++ b/plugins/fishlim/fishlim.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;FISHLIM_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/hextray/hextray.vcxproj b/plugins/hextray/hextray.vcxproj
index 9cac1368..3c48e9d0 100644
--- a/plugins/hextray/hextray.vcxproj
+++ b/plugins/hextray/hextray.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;XTRAY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -78,7 +77,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;XTRAY_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/mpcinfo/mpcinfo.vcxproj b/plugins/mpcinfo/mpcinfo.vcxproj
index a63962a9..756fddf2 100644
--- a/plugins/mpcinfo/mpcinfo.vcxproj
+++ b/plugins/mpcinfo/mpcinfo.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -78,7 +77,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;MPCINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/perl/perl.vcxproj b/plugins/perl/perl.vcxproj
index af173966..afaaa08f 100644
--- a/plugins/perl/perl.vcxproj
+++ b/plugins/perl/perl.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PERL518_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -89,7 +88,6 @@ move xchat.pm.h "$(IntDir)"</Command>
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PERL518_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/python/python.c b/plugins/python/python.c
index b34ed0a9..ade5de95 100644
--- a/plugins/python/python.c
+++ b/plugins/python/python.c
@@ -72,15 +72,32 @@
 #include <structmember.h>
 #include <pythread.h>
 
+/* Macros to convert version macros into string literals.
+ * The indirect macro is a well-known preprocessor trick to force X to be evaluated before the # operator acts to make it a string literal.
+ * If STRINGIZE were to be directly defined as #X instead, VERSION would be "VERSION_MAJOR" instead of "1".
+ */
+#define STRINGIZE2(X) #X
+#define STRINGIZE(X) STRINGIZE2(X)
+
+/* Version number macros */
 #define VERSION_MAJOR 1
 #define VERSION_MINOR 0
 
-#if PY_MAJOR_VERSION == 2
+/* Version string macro */
 #ifdef WIN32
-#undef WITH_THREAD
-#define VERSION "1.0/2.7"	/* Linked to python27.dll */
+#if PY_MAJOR_VERSION == 2
+#define VERSION STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "/2.7"	/* Linked to python27.dll */
+#elif PY_MAJOR_VERSION == 3
+#define VERSION STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR) "/3.3"	/* Linked to python33.dll */
+#endif
+#endif
+
+#ifndef VERSION
+#define VERSION STRINGIZE(VERSION_MAJOR) "." STRINGIZE(VERSION_MINOR)
 #endif
 
+/* #define's for Python 2 */
+#if PY_MAJOR_VERSION == 2
 #undef PyLong_Check
 #define PyLong_Check PyInt_Check
 #define PyLong_AsLong PyInt_AsLong
@@ -95,15 +112,14 @@
 #define PyUnicode_FromString PyString_FromString
 #define PyUnicode_AsUTF8 PyString_AsString
 
-#else
-#define IS_PY3K
 #ifdef WIN32
-#define VERSION "1.0/3.3"	/* Linked to python33.dll */
+#undef WITH_THREAD
 #endif
 #endif
 
-#ifndef VERSION
-#define VERSION "1.0"
+/* #define for Python 3 */
+#if PY_MAJOR_VERSION == 3
+#define IS_PY3K
 #endif
 
 #define NONE 0
@@ -211,7 +227,8 @@ static PyThreadState *pTempThread;
 	((PluginObject *)(x))->gui = (y);
 
 #define HOOK_XCHAT  1
-#define HOOK_UNLOAD 2
+#define HOOK_XCHAT_ATTR 2
+#define HOOK_UNLOAD 3
 
 /* ===================================================================== */
 /* Object definitions */
@@ -228,6 +245,11 @@ typedef struct {
 
 typedef struct {
 	PyObject_HEAD
+	PyObject *time;
+} AttributeObject;
+
+typedef struct {
+	PyObject_HEAD
 	const char *listname;
 	PyObject *dict;
 } ListItemObject;
@@ -261,7 +283,9 @@ static PyObject *Util_BuildList(char *word[]);
 static void Util_Autoload();
 static char *Util_Expand(char *filename);
 
+static int Callback_Server(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata);
 static int Callback_Command(char *word[], char *word_eol[], void *userdata);
+static int Callback_Print_Attrs(char *word[], hexchat_event_attrs *attrs, void *userdata);
 static int Callback_Print(char *word[], void *userdata);
 static int Callback_Timer(void *userdata);
 static int Callback_ThreadTimer(void *userdata);
@@ -270,6 +294,8 @@ static PyObject *XChatOut_New();
 static PyObject *XChatOut_write(PyObject *self, PyObject *args);
 static void XChatOut_dealloc(PyObject *self);
 
+static PyObject *Attribute_New(hexchat_event_attrs *attrs);
+
 static void Context_dealloc(PyObject *self);
 static PyObject *Context_set(ContextObject *self, PyObject *args);
 static PyObject *Context_command(ContextObject *self, PyObject *args);
@@ -331,6 +357,7 @@ static PyTypeObject Plugin_Type;
 static PyTypeObject XChatOut_Type;
 static PyTypeObject Context_Type;
 static PyTypeObject ListItem_Type;
+static PyTypeObject Attribute_Type;
 
 static PyThreadState *main_tstate = NULL;
 static void *thread_timer = NULL;
@@ -488,6 +515,58 @@ Util_ReleaseThread(PyThreadState *tstate)
  * the load function, and the hooks for interactive interpreter. */
 
 static int
+Callback_Server(char *word[], char *word_eol[], hexchat_event_attrs *attrs, void *userdata)
+{
+	Hook *hook = (Hook *) userdata;
+	PyObject *retobj;
+	PyObject *word_list, *word_eol_list;
+	PyObject *attributes;
+	int ret = 0;
+	PyObject *plugin;
+
+	plugin = hook->plugin;
+	BEGIN_PLUGIN(plugin);
+
+	word_list = Util_BuildList(word+1);
+	if (word_list == NULL) {
+		END_PLUGIN(plugin);
+		return 0;
+	}
+	word_eol_list = Util_BuildList(word_eol+1);
+	if (word_eol_list == NULL) {
+		Py_DECREF(word_list);
+		END_PLUGIN(plugin);
+		return 0;
+	}
+
+	attributes = Attribute_New(attrs);
+
+	if (hook->type == HOOK_XCHAT_ATTR)
+		retobj = PyObject_CallFunction(hook->callback, "(OOOO)", word_list,
+					       word_eol_list, hook->userdata, attributes);
+	else
+		retobj = PyObject_CallFunction(hook->callback, "(OOO)", word_list,
+					       word_eol_list, hook->userdata);
+	Py_DECREF(word_list);
+	Py_DECREF(word_eol_list);
+	Py_DECREF(attributes);
+
+	if (retobj == Py_None) {
+		ret = HEXCHAT_EAT_NONE;
+		Py_DECREF(retobj);
+	} else if (retobj) {
+		ret = PyLong_AsLong(retobj);
+		Py_DECREF(retobj);
+	} else {
+		PyErr_Print();
+	}
+
+	END_PLUGIN(plugin);
+
+	return ret;
+}
+
+static int
 Callback_Command(char *word[], char *word_eol[], void *userdata)
 {
 	Hook *hook = (Hook *) userdata;
@@ -531,7 +610,96 @@ Callback_Command(char *word[], char *word_eol[], void *userdata)
 	return ret;
 }
 
-/* No Callback_Server() here. We use Callback_Command() as well. */
+static int
+Callback_Print_Attrs(char *word[], hexchat_event_attrs *attrs, void *userdata)
+{
+	Hook *hook = (Hook *) userdata;
+	PyObject *retobj;
+	PyObject *word_list;
+	PyObject *word_eol_list;
+	PyObject *attributes;
+	char **word_eol;
+	char *word_eol_raw;
+	int listsize = 0;
+	int next = 0;
+	int i;
+	int ret = 0;
+	PyObject *plugin;
+
+	/* Cut off the message identifier. */
+	word += 1;
+
+	/* HexChat doesn't provide a word_eol for print events, so we
+	 * build our own here. */
+	while (word[listsize] && word[listsize][0])
+		listsize++;
+	word_eol = (char **) g_malloc(sizeof(char*)*(listsize+1));
+	if (word_eol == NULL) {
+		hexchat_print(ph, "Not enough memory to alloc word_eol "
+				"for python plugin callback.");
+		return 0;
+	}
+	/* First build a word clone, but NULL terminated. */
+	memcpy(word_eol, word, listsize*sizeof(char*));
+	word_eol[listsize] = NULL;
+	/* Then join it. */
+	word_eol_raw = g_strjoinv(" ", word_eol);
+	if (word_eol_raw == NULL) {
+		hexchat_print(ph, "Not enough memory to alloc word_eol_raw "
+				"for python plugin callback.");
+		return 0;
+	}
+	/* And rebuild the real word_eol. */
+	for (i = 0; i != listsize; i++) {
+		word_eol[i] = word_eol_raw+next;
+		next += strlen(word[i])+1;
+	}
+	word_eol[i] = "";
+
+	plugin = hook->plugin;
+	BEGIN_PLUGIN(plugin);
+
+	word_list = Util_BuildList(word);
+	if (word_list == NULL) {
+		g_free(word_eol_raw);
+		g_free(word_eol);
+		END_PLUGIN(plugin);
+		return 0;
+	}
+	word_eol_list = Util_BuildList(word_eol);
+	if (word_eol_list == NULL) {
+		g_free(word_eol_raw);
+		g_free(word_eol);
+		Py_DECREF(word_list);
+		END_PLUGIN(plugin);
+		return 0;
+	}
+
+	attributes = Attribute_New(attrs);
+
+	retobj = PyObject_CallFunction(hook->callback, "(OOOO)", word_list,
+					    word_eol_list, hook->userdata, attributes);
+
+	Py_DECREF(word_list);
+	Py_DECREF(word_eol_list);
+	Py_DECREF(attributes);
+
+	g_free(word_eol_raw);
+	g_free(word_eol);
+	if (retobj == Py_None) {
+		ret = HEXCHAT_EAT_NONE;
+		Py_DECREF(retobj);
+	} else if (retobj) {
+		ret = PyLong_AsLong(retobj);
+		Py_DECREF(retobj);
+	} else {
+		PyErr_Print();
+	}
+
+	END_PLUGIN(plugin);
+
+	return ret;
+}
 
 static int
 Callback_Print(char *word[], void *userdata)
@@ -597,8 +765,10 @@ Callback_Print(char *word[], void *userdata)
 		return 0;
 	}
 
+
 	retobj = PyObject_CallFunction(hook->callback, "(OOO)", word_list,
-				       word_eol_list, hook->userdata);
+					       word_eol_list, hook->userdata);
+
 	Py_DECREF(word_list);
 	Py_DECREF(word_eol_list);
 
@@ -823,6 +993,85 @@ static PyTypeObject XChatOut_Type = {
 
 
 /* ===================================================================== */
+/* Attribute object */
+
+#undef OFF
+#define OFF(x) offsetof(AttributeObject, x)
+
+static PyMemberDef Attribute_members[] = {
+	{"time", T_OBJECT, OFF(time), 0},
+	{0}
+};
+
+static void
+Attribute_dealloc(PyObject *self)
+{
+	Py_DECREF(((AttributeObject*)self)->time);
+	Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Attribute_repr(PyObject *self)
+{
+	return PyUnicode_FromFormat("<Attribute object at %p>", self);
+}
+
+static PyTypeObject Attribute_Type = {
+	PyVarObject_HEAD_INIT(NULL, 0)
+	"hexchat.Attribute",	/*tp_name*/
+	sizeof(AttributeObject),	/*tp_basicsize*/
+	0,			/*tp_itemsize*/
+	Attribute_dealloc,	/*tp_dealloc*/
+	0,			/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	Attribute_repr,		/*tp_repr*/
+	0,			/*tp_as_number*/
+	0,			/*tp_as_sequence*/
+	0,			/*tp_as_mapping*/
+	0,			/*tp_hash*/
+        0,                      /*tp_call*/
+        0,                      /*tp_str*/
+        PyObject_GenericGetAttr,/*tp_getattro*/
+        PyObject_GenericSetAttr,/*tp_setattro*/
+        0,                      /*tp_as_buffer*/
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+        0,                      /*tp_doc*/
+        0,                      /*tp_traverse*/
+        0,                      /*tp_clear*/
+        0,                      /*tp_richcompare*/
+        0,                      /*tp_weaklistoffset*/
+        0,                      /*tp_iter*/
+        0,                      /*tp_iternext*/
+        0,                      /*tp_methods*/
+        Attribute_members,		/*tp_members*/
+        0,                      /*tp_getset*/
+        0,                      /*tp_base*/
+        0,                      /*tp_dict*/
+        0,                      /*tp_descr_get*/
+        0,                      /*tp_descr_set*/
+        0,						/*tp_dictoffset*/
+        0,                      /*tp_init*/
+        PyType_GenericAlloc,    /*tp_alloc*/
+        PyType_GenericNew,      /*tp_new*/
+      	PyObject_Del,          /*tp_free*/
+        0,                      /*tp_is_gc*/
+};
+
+static PyObject *
+Attribute_New(hexchat_event_attrs *attrs)
+{
+	AttributeObject *attr;
+	attr = PyObject_New(AttributeObject, &Attribute_Type);
+	if (attr != NULL) {
+		attr->time = PyLong_FromLong((long)attrs->server_time_utc);
+	}
+	return (PyObject *) attr;
+}
+
+
+/* ===================================================================== */
 /* Context object */
 
 static void
@@ -869,22 +1118,31 @@ Context_prnt(ContextObject *self, PyObject *args)
 }
 
 static PyObject *
-Context_emit_print(ContextObject *self, PyObject *args)
+Context_emit_print(ContextObject *self, PyObject *args, PyObject *kwargs)
 {
-	char *argv[10];
+	char *argv[6];
 	char *name;
 	int res;
-	memset(&argv, 0, sizeof(char*)*10);
-	if (!PyArg_ParseTuple(args, "s|ssssss:print_event", &name,
+	long time = 0;
+	hexchat_event_attrs *attrs;
+	char *kwlist[] = {"name", "arg1", "arg2", "arg3",
+					"arg4", "arg5", "arg6", 
+					"time", NULL};
+	memset(&argv, 0, sizeof(char*)*6);
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssssssl:print_event", kwlist, &name,
 			      &argv[0], &argv[1], &argv[2],
 			      &argv[3], &argv[4], &argv[5],
-			      &argv[6], &argv[7], &argv[8]))
+				  &time))
 		return NULL;
 	BEGIN_XCHAT_CALLS(ALLOW_THREADS);
 	hexchat_set_context(ph, self->context);
-	res = hexchat_emit_print(ph, name, argv[0], argv[1], argv[2],
-					 argv[3], argv[4], argv[5],
-					 argv[6], argv[7], argv[8]);
+	attrs = hexchat_event_attrs_create(ph);
+	attrs->server_time_utc = (time_t)time; 
+	
+	res = hexchat_emit_print_attrs(ph, attrs, name, argv[0], argv[1], argv[2],
+					 argv[3], argv[4], argv[5], NULL);
+
+	hexchat_event_attrs_free(ph, attrs);
 	END_XCHAT_CALLS();
 	return PyLong_FromLong(res);
 }
@@ -945,7 +1203,7 @@ static PyMethodDef Context_methods[] = {
 	{"set", (PyCFunction) Context_set, METH_NOARGS},
 	{"command", (PyCFunction) Context_command, METH_VARARGS},
 	{"prnt", (PyCFunction) Context_prnt, METH_VARARGS},
-	{"emit_print", (PyCFunction) Context_emit_print, METH_VARARGS},
+	{"emit_print", (PyCFunction) Context_emit_print, METH_VARARGS|METH_KEYWORDS},
 	{"get_info", (PyCFunction) Context_get_info, METH_VARARGS},
 	{"get_list", (PyCFunction) Context_get_list, METH_VARARGS},
 	{NULL, NULL}
@@ -1232,7 +1490,7 @@ Plugin_RemoveHook(PyObject *plugin, Hook *hook)
 	list = g_slist_find(Plugin_GetHooks(plugin), hook);
 	if (list) {
 		/* Ok, unhook it. */
-		if (hook->type == HOOK_XCHAT) {
+		if (hook->type != HOOK_UNLOAD) {
 			/* This is an xchat hook. Unregister it. */
 			BEGIN_XCHAT_CALLS(NONE);
 			hexchat_unhook(ph, (hexchat_hook*)hook->data);
@@ -1255,7 +1513,7 @@ Plugin_RemoveAllHooks(PyObject *plugin)
 	GSList *list = Plugin_GetHooks(plugin);
 	while (list) {
 		Hook *hook = (Hook *) list->data;
-		if (hook->type == HOOK_XCHAT) {
+		if (hook->type != HOOK_UNLOAD) {
 			/* This is an xchat hook. Unregister it. */
 			BEGIN_XCHAT_CALLS(NONE);
 			hexchat_unhook(ph, (hexchat_hook*)hook->data);
@@ -1511,21 +1769,30 @@ Module_xchat_prnt(PyObject *self, PyObject *args)
 }
 
 static PyObject *
-Module_hexchat_emit_print(PyObject *self, PyObject *args)
+Module_hexchat_emit_print(PyObject *self, PyObject *args, PyObject *kwargs)
 {
-	char *argv[10];
+	char *argv[6];
 	char *name;
 	int res;
-	memset(&argv, 0, sizeof(char*)*10);
-	if (!PyArg_ParseTuple(args, "s|ssssss:print_event", &name,
+	long time = 0;
+	hexchat_event_attrs *attrs;
+	char *kwlist[] = {"name", "arg1", "arg2", "arg3",
+					"arg4", "arg5", "arg6", 
+					"time", NULL};
+	memset(&argv, 0, sizeof(char*)*6);
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ssssssl:print_event", kwlist, &name,
 			      &argv[0], &argv[1], &argv[2],
 			      &argv[3], &argv[4], &argv[5],
-			      &argv[6], &argv[7], &argv[8]))
+				  &time))
 		return NULL;
 	BEGIN_XCHAT_CALLS(RESTORE_CONTEXT|ALLOW_THREADS);
-	res = hexchat_emit_print(ph, name, argv[0], argv[1], argv[2],
-					 argv[3], argv[4], argv[5],
-					 argv[6], argv[7], argv[8]);
+	attrs = hexchat_event_attrs_create(ph);
+	attrs->server_time_utc = (time_t)time; 
+	
+	res = hexchat_emit_print_attrs(ph, attrs, name, argv[0], argv[1], argv[2],
+					 argv[3], argv[4], argv[5], NULL);
+
+	hexchat_event_attrs_free(ph, attrs);
 	END_XCHAT_CALLS();
 	return PyLong_FromLong(res);
 }
@@ -1757,7 +2024,7 @@ Module_hexchat_hook_command(PyObject *self, PyObject *args, PyObject *kwargs)
 					       Callback_Command, help, hook);
 	END_XCHAT_CALLS();
 
-	return PyLong_FromLong((long)hook);
+	return PyLong_FromVoidPtr(hook);
 }
 
 static PyObject *
@@ -1789,11 +2056,47 @@ Module_hexchat_hook_server(PyObject *self, PyObject *args, PyObject *kwargs)
 		return NULL;
 
 	BEGIN_XCHAT_CALLS(NONE);
-	hook->data = (void*)hexchat_hook_server(ph, name, priority,
-					      Callback_Command, hook);
+	hook->data = (void*)hexchat_hook_server_attrs(ph, name, priority,
+					      Callback_Server, hook);
+	END_XCHAT_CALLS();
+
+	return PyLong_FromVoidPtr(hook);
+}
+
+static PyObject *
+Module_hexchat_hook_server_attrs(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	char *name;
+	PyObject *callback;
+	PyObject *userdata = Py_None;
+	int priority = HEXCHAT_PRI_NORM;
+	PyObject *plugin;
+	Hook *hook;
+	char *kwlist[] = {"name", "callback", "userdata", "priority", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|Oi:hook_server",
+					 kwlist, &name, &callback, &userdata,
+					 &priority))
+		return NULL;
+
+	plugin = Plugin_GetCurrent();
+	if (plugin == NULL)
+		return NULL;
+	if (!PyCallable_Check(callback)) {
+		PyErr_SetString(PyExc_TypeError, "callback is not callable");
+		return NULL;
+	}
+
+	hook = Plugin_AddHook(HOOK_XCHAT_ATTR, plugin, callback, userdata, NULL, NULL);
+	if (hook == NULL)
+		return NULL;
+
+	BEGIN_XCHAT_CALLS(NONE);
+	hook->data = (void*)hexchat_hook_server_attrs(ph, name, priority,
+					      Callback_Server, hook);
 	END_XCHAT_CALLS();
 
-	return PyLong_FromLong((long)hook);
+	return PyLong_FromVoidPtr(hook);
 }
 
 static PyObject *
@@ -1829,7 +2132,43 @@ Module_hexchat_hook_print(PyObject *self, PyObject *args, PyObject *kwargs)
 					     Callback_Print, hook);
 	END_XCHAT_CALLS();
 
-	return PyLong_FromLong((long)hook);
+	return PyLong_FromVoidPtr(hook);
+}
+
+static PyObject *
+Module_hexchat_hook_print_attrs(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	char *name;
+	PyObject *callback;
+	PyObject *userdata = Py_None;
+	int priority = HEXCHAT_PRI_NORM;
+	PyObject *plugin;
+	Hook *hook;
+	char *kwlist[] = {"name", "callback", "userdata", "priority", 0};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|Oi:hook_print_attrs",
+					 kwlist, &name, &callback, &userdata,
+					 &priority))
+		return NULL;
+
+	plugin = Plugin_GetCurrent();
+	if (plugin == NULL)
+		return NULL;
+	if (!PyCallable_Check(callback)) {
+		PyErr_SetString(PyExc_TypeError, "callback is not callable");
+		return NULL;
+	}
+
+	hook = Plugin_AddHook(HOOK_XCHAT_ATTR, plugin, callback, userdata, name, NULL);
+	if (hook == NULL)
+		return NULL;
+
+	BEGIN_XCHAT_CALLS(NONE);
+	hook->data = (void*)hexchat_hook_print_attrs(ph, name, priority,
+					     Callback_Print_Attrs, hook);
+	END_XCHAT_CALLS();
+
+	return PyLong_FromVoidPtr(hook);
 }
 
 static PyObject *
@@ -1864,7 +2203,7 @@ Module_hexchat_hook_timer(PyObject *self, PyObject *args, PyObject *kwargs)
 					     Callback_Timer, hook);
 	END_XCHAT_CALLS();
 
-	return PyLong_FromLong((long)hook);
+	return PyLong_FromVoidPtr(hook);
 }
 
 static PyObject *
@@ -1892,7 +2231,7 @@ Module_hexchat_hook_unload(PyObject *self, PyObject *args, PyObject *kwargs)
 	if (hook == NULL)
 		return NULL;
 
-	return PyLong_FromLong((long)hook);
+	return PyLong_FromVoidPtr(hook);
 }
 
 static PyObject *
@@ -1918,7 +2257,7 @@ Module_hexchat_unhook(PyObject *self, PyObject *args)
 	}
 	else
 	{
-		hook = (Hook *)PyLong_AsLong(obj);
+		hook = (Hook *)PyLong_AsVoidPtr(obj);
 		Plugin_RemoveHook(plugin, hook);
 	}	
 
@@ -2066,8 +2405,8 @@ static PyMethodDef Module_xchat_methods[] = {
 		METH_VARARGS},
 	{"prnt",		Module_xchat_prnt,
 		METH_VARARGS},
-	{"emit_print",		Module_hexchat_emit_print,
-		METH_VARARGS},
+	{"emit_print",		(PyCFunction)Module_hexchat_emit_print,
+		METH_VARARGS|METH_KEYWORDS},
 	{"get_info",		Module_hexchat_get_info,
 		METH_VARARGS},
 	{"get_prefs",		Module_xchat_get_prefs,
@@ -2088,8 +2427,12 @@ static PyMethodDef Module_xchat_methods[] = {
 		METH_VARARGS|METH_KEYWORDS},
 	{"hook_server",		(PyCFunction)Module_hexchat_hook_server,
 		METH_VARARGS|METH_KEYWORDS},
+	{"hook_server_attrs",		(PyCFunction)Module_hexchat_hook_server_attrs,
+		METH_VARARGS|METH_KEYWORDS},
 	{"hook_print",		(PyCFunction)Module_hexchat_hook_print,
 		METH_VARARGS|METH_KEYWORDS},
+	{"hook_print_attrs",		(PyCFunction)Module_hexchat_hook_print_attrs,
+		METH_VARARGS|METH_KEYWORDS},
 	{"hook_timer",		(PyCFunction)Module_hexchat_hook_timer,
 		METH_VARARGS|METH_KEYWORDS},
 	{"hook_unload",		(PyCFunction)Module_hexchat_hook_unload,
diff --git a/plugins/python/python2.vcxproj b/plugins/python/python2.vcxproj
index 1f524134..6730f45e 100644
--- a/plugins/python/python2.vcxproj
+++ b/plugins/python/python2.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/python/python3.vcxproj b/plugins/python/python3.vcxproj
index ddf56132..28ffc80c 100644
--- a/plugins/python/python3.vcxproj
+++ b/plugins/python/python3.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;PYTHON_EXPORTS;$(OwnFlags);%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/sysinfo/sysinfo.vcxproj b/plugins/sysinfo/sysinfo.vcxproj
index 0446e723..88c090cc 100644
--- a/plugins/sysinfo/sysinfo.vcxproj
+++ b/plugins/sysinfo/sysinfo.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -81,7 +80,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;SYSINFO_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/upd/upd.c b/plugins/upd/upd.c
index 3ab8edd5..7ebf95bc 100644
--- a/plugins/upd/upd.c
+++ b/plugins/upd/upd.c
@@ -27,8 +27,9 @@
 
 #include "hexchat-plugin.h"
 
-#define DEFAULT_DELAY 10	/* 10 seconds */
+#define DEFAULT_DELAY 30	/* 30 seconds */
 #define DEFAULT_FREQ 360	/* 6 hours */
+#define DOWNLOAD_URL "http://dl.hexchat.net/hexchat"
 
 static hexchat_plugin *ph;   /* plugin handle */
 static char name[] = "Update Checker";
@@ -39,61 +40,6 @@ static const char upd_help[] = "Update Checker Usage:\n  /UPDCHK, check for HexC
 static char*
 check_version ()
 {
-#if 0
-	HINTERNET hINet, hFile;
-	hINet = InternetOpen ("Update Checker", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
-
-	if (!hINet)
-	{
-		return "Unknown";
-	}
-
-	hFile = InternetOpenUrl (hINet,
-							"https://raw.github.com/hexchat/hexchat/master/win32/version.txt",
-							NULL,
-							0,
-							INTERNET_FLAG_NO_CACHE_WRITE | INTERNET_FLAG_RELOAD,
-							0);
-	if (hFile)
-	{
-		static char buffer[1024];
-		DWORD dwRead;
-		while (InternetReadFile (hFile, buffer, 1023, &dwRead))
-		{
-			if (dwRead == 0)
-			{
-				break;
-			}
-			buffer[dwRead] = 0;
-		}
-
-		InternetCloseHandle (hFile);
-		InternetCloseHandle (hINet);
-		if (strlen (buffer) == 5)
-			return buffer;
-		else
-			return "Unknown";
-	}
-
-	InternetCloseHandle (hINet);
-	return "Unknown";
-#endif
-
-	/* Google Code's messing up with requests, use HTTP/1.0 as suggested. More info:
-
-	   http://code.google.com/p/support/issues/detail?id=6095
-
-	   Of course it would be still too simple, coz IE will override settings, so
-	   you have to disable HTTP/1.1 manually and globally. More info:
-
-	   http://support.microsoft.com/kb/258425
-
-	   So this code's basically useless since disabling HTTP/1.1 will work with the
-	   above code too.
-
-	   Update: a Connection: close header seems to disable chunked encoding.
-	*/
-
 	HINTERNET hOpen, hConnect, hResource;
 
 	hOpen = InternetOpen (TEXT ("Update Checker"),
@@ -137,7 +83,11 @@ check_version ()
 	else
 	{
 		static char buffer[1024];
+		char infobuffer[32];
+		int statuscode;
+
 		DWORD dwRead;
+		DWORD infolen = sizeof(infobuffer);
 
 		HttpAddRequestHeaders (hResource, TEXT ("Connection: close\r\n"), -1L, HTTP_ADDREQ_FLAG_ADD);	/* workaround for GC bug */
 		HttpSendRequest (hResource, NULL, 0, NULL, 0);
@@ -151,10 +101,18 @@ check_version ()
 			buffer[dwRead] = 0;
 		}
 
+		HttpQueryInfo(hResource,
+					HTTP_QUERY_STATUS_CODE,
+					&infobuffer,
+					&infolen,
+					NULL);
+
 		InternetCloseHandle (hResource);
 		InternetCloseHandle (hConnect);
 		InternetCloseHandle (hOpen);
-		if (strlen (buffer) == 5)
+
+		statuscode = atoi(infobuffer);
+		if (statuscode == 200)
 			return buffer;
 		else
 			return "Unknown";
@@ -233,9 +191,9 @@ print_version (char *word[], char *word_eol[], void *userdata)
 		else
 		{
 #ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for some reason */
-			hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttp://dl.hexchat.org/hexchat/HexChat%%20%s%%20x64.exe\n", name, version);
+			hexchat_printf (ph, "%s:\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x64.exe\n", name, DOWNLOAD_URL, version);
 #else
-			hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttp://dl.hexchat.org/hexchat/HexChat%%20%s%%20x86.exe\n", name, version);
+			hexchat_printf (ph, "%s:\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x86.exe\n", name, DOWNLOAD_URL, version);
 #endif
 		}
 		return HEXCHAT_EAT_HEXCHAT;
@@ -256,9 +214,9 @@ print_version_quiet (void *userdata)
 	if (!(strcmp (version, hexchat_get_info (ph, "version")) == 0) && !(strcmp (version, "Unknown") == 0))
 	{
 #ifdef _WIN64 /* use this approach, the wProcessorArchitecture method always returns 0 (=x86) for plugins for some reason */
-		hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttps://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x64.exe\n", name, version);
+		hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x64.exe\n", name, DOWNLOAD_URL, version);
 #else
-		hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\nhttps://github.com/downloads/hexchat/hexchat/HexChat%%20%s%%20x86.exe\n", name, version);
+		hexchat_printf (ph, "%s\tA HexChat update is available! You can download it from here:\n%s/HexChat%%20%s%%20x86.exe\n", name, DOWNLOAD_URL, version);
 #endif
 		/* print update url once, then stop the timer */
 		return 0;
diff --git a/plugins/upd/upd.vcxproj b/plugins/upd/upd.vcxproj
index 1b3009dc..a06085b2 100644
--- a/plugins/upd/upd.vcxproj
+++ b/plugins/upd/upd.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -80,7 +79,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;UPD_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

diff --git a/plugins/winamp/winamp.vcxproj b/plugins/winamp/winamp.vcxproj
index 667ec598..e140f55f 100644
--- a/plugins/winamp/winamp.vcxproj
+++ b/plugins/winamp/winamp.vcxproj
@@ -59,7 +59,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>

@@ -78,7 +77,6 @@
     <ClCompile>

       <PrecompiledHeader>

       </PrecompiledHeader>

-      <Optimization>MaxSpeed</Optimization>

       <FunctionLevelLinking>true</FunctionLevelLinking>

       <IntrinsicFunctions>true</IntrinsicFunctions>

       <PreprocessorDefinitions>WIN32;_WIN64;_AMD64_;NDEBUG;_WINDOWS;_USRDLL;WINAMP_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>