Index: protocols/rpc/rpc.c
===================================================================
--- protocols/rpc/rpc.c	(revision f81d8b84296c11c0a5a7f2727f3cd8c80178a76a)
+++ protocols/rpc/rpc.c	(revision 6f903c356568d9c63807bbebe2d817edcbc4dad0)
@@ -50,5 +50,5 @@
 		 * Not sure whether to use it. */
 		JSON_Value *error = json_value_init_object();
-		json_object_set_number(json_object(error), "code", code);
+		json_object_set_integer(json_object(error), "code", code);
 		json_object_set_string(json_object(error), "message", msg);
 		json_object_set_value(json_object(ret), "error", error);
@@ -78,5 +78,5 @@
 	JSON_Value *rpc = json_value_init_object();
 	json_object_set_string(json_object(rpc), "method", method);
-	json_object_set_number(json_object(rpc), "id", next_rpc_id++);
+	json_object_set_integer(json_object(rpc), "id", next_rpc_id++);
 
 	JSON_Value *params = json_value_init_array();
@@ -147,9 +147,9 @@
 	json_object_set_string_or_null(o, "nick", bu->nick);
 	json_object_set_string_or_null(o, "group", bu->group ? bu->group->name : NULL);
-	json_object_set_number(o, "flags", bu->flags);
+	json_object_set_integer(o, "flags", bu->flags);
 	json_object_set_string_or_null(o, "status", bu->status);
 	json_object_set_string_or_null(o, "status_msg", bu->status_msg);
-	json_object_set_number(o, "login_time", bu->login_time);
-	json_object_set_number(o, "idle_time", bu->idle_time);
+	json_object_set_integer(o, "login_time", bu->login_time);
+	json_object_set_integer(o, "idle_time", bu->idle_time);
 	return v;
 }
@@ -163,7 +163,5 @@
 		JSON_Object *o = json_object(value);
 		set_t *set = set_add(&acc->set, name, json_object_get_string(o, "default"), NULL, acc);
-		/* JSON numbers are floats. The following line "might" be a
-		 * terrible idea. As was JSON, but hey. */
-		set->flags |= (int) json_object_get_number(o, "flags");
+		set->flags |= json_object_get_integer(o, "flags");
 		set->eval = rpc_set_evaluator;
 		set->eval_data = o;
@@ -210,5 +208,5 @@
 			/* Evaluator already did validation so ignore retval. */
 			sscanf(value, "%d", &num);
-			json_array_append_number(params, num);
+			json_array_append_integer(params, num);
 		} else if (type_eval == set_eval_bool) {
 			json_array_append_boolean(params, bool2int(value));
@@ -285,5 +283,5 @@
 	json_array_append_string(params, to);
 	json_array_append_string(params, message);
-	json_array_append_number(params, flags);
+	json_array_append_integer(params, flags);
 	return rpc_send(ic, rpc);
 }
@@ -299,5 +297,5 @@
 	RPC_OUT_INIT("send_typing");
 	json_array_append_string(params, who);
-	json_array_append_number(params, flags);
+	json_array_append_integer(params, flags);
 	return rpc_send(ic, rpc);
 }
@@ -350,5 +348,5 @@
 	RPC_OUT_INIT("chat_invite");
 	struct rpc_groupchat *rc = gc->data;
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, who);
 	json_array_append_string_or_null(params, message);
@@ -359,5 +357,5 @@
 	RPC_OUT_INIT("chat_kick");
 	struct rpc_groupchat *rc = gc->data;
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, who);
 	json_array_append_string_or_null(params, message);
@@ -368,5 +366,5 @@
 	RPC_OUT_INIT("chat_leave");
 	struct rpc_groupchat *rc = gc->data;
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	rpc_send(gc->ic, rpc);
 }
@@ -375,7 +373,7 @@
 	RPC_OUT_INIT("chat_msg");	
 	struct rpc_groupchat *rc = gc->data;
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, msg);
-	json_array_append_number(params, flags);
+	json_array_append_integer(params, flags);
 	rpc_send(gc->ic, rpc);
 }
@@ -402,5 +400,5 @@
 #define SET_GROUPCHAT(rc) \
 	do { \
-		rc = rpc_groupchat_by_id(ic, json_array_get_number(params, 0)); \
+		rc = rpc_groupchat_by_id(ic, json_array_get_integer(params, 0)); \
 		if (rc == NULL) \
 			return jsonrpc_error(ENOENT, "No groupchat with that id."); \
@@ -410,5 +408,5 @@
 	RPC_OUT_INIT("chat_with");
 	struct rpc_groupchat *rc = rpc_groupchat_new(ic, who);
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, who);
 	rpc_send(ic, rpc);
@@ -421,5 +419,5 @@
 	RPC_OUT_INIT("chat_join");
 	struct rpc_groupchat *rc = rpc_groupchat_new(ic, room);
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, room);
 	json_array_append_string_or_null(params, nick);
@@ -434,5 +432,5 @@
 	RPC_OUT_INIT("chat_topic");
 	struct rpc_groupchat *rc = gc->data;
-	json_array_append_number(params, rc->id);
+	json_array_append_integer(params, rc->id);
 	json_array_append_string(params, topic);
 	rpc_send(gc->ic, rpc);
@@ -551,5 +549,5 @@
 static JSON_Value *rpc_imcb_buddy_status(struct im_connection *ic, void *func_, JSON_Array *params) {
 	void (*func)(struct im_connection*, const char*, int, const char*, const char*) = func_;
-	func(ic, json_array_get_string(params, 0), json_array_get_number(params, 1),
+	func(ic, json_array_get_string(params, 0), json_array_get_integer(params, 1),
 	         json_array_get_string(params, 2), json_array_get_string(params, 3));
 	return NULL;
@@ -558,6 +556,6 @@
 static JSON_Value *rpc_imcb_buddy_times(struct im_connection *ic, void *func_, JSON_Array *params) {
 	void (*func)(struct im_connection*, const char*, int, int) = func_;
-	func(ic, json_array_get_string(params, 0), json_array_get_number(params, 1),
-	         json_array_get_number(params, 2));
+	func(ic, json_array_get_string(params, 0), json_array_get_integer(params, 1),
+	         json_array_get_integer(params, 2));
 	return NULL;
 }
@@ -566,5 +564,5 @@
 	void (*func)(struct im_connection*, const char*, const char*, int, int) = func_;
 	func(ic, json_array_get_string(params, 0), json_array_get_string(params, 1),
-	         json_array_get_number(params, 2), json_array_get_number(params, 3));
+	         json_array_get_integer(params, 2), json_array_get_integer(params, 3));
 	return NULL;
 }
@@ -572,5 +570,5 @@
 static JSON_Value *rpc_imcb_buddy_typing(struct im_connection *ic, void *func_, JSON_Array *params) {
 	void (*func)(struct im_connection*, const char*, int) = func_;
-	func(ic, (char*) json_array_get_string(params, 0), json_array_get_number(params, 1));
+	func(ic, (char*) json_array_get_string(params, 0), json_array_get_integer(params, 1));
 	return NULL;
 }
@@ -579,5 +577,5 @@
 	struct rpc_groupchat *rc = rpc_groupchat_new(ic, json_array_get_string(params, 0));
 	JSON_Value *resp = json_value_init_object();
-	json_object_set_number(json_object(resp), "result", rc->id);
+	json_object_set_integer(json_object(resp), "result", rc->id);
 	return resp;
 }
@@ -596,5 +594,5 @@
 	SET_GROUPCHAT(rc);
 	func(rc->gc, json_array_get_string(params, 1), json_array_get_string(params, 2),
-	     json_array_get_number(params, 3), json_array_get_number(params, 4));
+	     json_array_get_integer(params, 3), json_array_get_integer(params, 4));
 	return NULL;
 }
@@ -613,5 +611,5 @@
 	SET_GROUPCHAT(rc);
 	func(rc->gc, json_array_get_string(params, 1), json_array_get_string(params, 2),
-	     json_array_get_number(params, 3));
+	     json_array_get_integer(params, 3));
 	return NULL;
 }
@@ -687,18 +685,18 @@
 	{ "imcb_buddy_status", imcb_buddy_status, rpc_imcb_buddy_status, "snss" },
 	{ "imcb_buddy_status_msg", imcb_buddy_status_msg, rpc_imcb_add_buddy, "ss" },
-	{ "imcb_buddy_times", imcb_buddy_times, rpc_imcb_buddy_times, "snn" },
-	{ "imcb_buddy_msg", imcb_buddy_msg, rpc_imcb_buddy_msg, "ssnn" },
-	{ "imcb_buddy_typing", imcb_buddy_typing, rpc_imcb_buddy_typing, "sn" },
+	{ "imcb_buddy_times", imcb_buddy_times, rpc_imcb_buddy_times, "sii" },
+	{ "imcb_buddy_msg", imcb_buddy_msg, rpc_imcb_buddy_msg, "ssii" },
+	{ "imcb_buddy_typing", imcb_buddy_typing, rpc_imcb_buddy_typing, "si" },
 	{ "imcb_chat_new", NULL, rpc_imcb_chat_new, "s" },
 	
 	/* RPCs below are equivalent, but with the struct groupchat* replaced
 	 * with the numeric id of the chat. */
-	{ "imcb_chat_name_hint", imcb_chat_name_hint, rpc_imcb_chat_name_hint, "ns" },
-	{ "imcb_chat_msg", imcb_chat_msg, rpc_imcb_chat_msg, "nssnn" },
-	{ "imcb_chat_log", imcb_chat_log, rpc_imcb_chat_log, "ns" },
-	{ "imcb_chat_topic", imcb_chat_topic, rpc_imcb_chat_topic, "nssn" },
-	{ "imcb_chat_add_buddy", imcb_chat_add_buddy, rpc_imcb_chat_name_hint, "ns" },
-	{ "imcb_chat_remove_buddy", imcb_chat_remove_buddy, rpc_imcb_chat_remove_buddy, "nss" },
-	{ "imcb_chat_invite", imcb_chat_invite, rpc_imcb_chat_invite, "nsss" },
+	{ "imcb_chat_name_hint", imcb_chat_name_hint, rpc_imcb_chat_name_hint, "is" },
+	{ "imcb_chat_msg", imcb_chat_msg, rpc_imcb_chat_msg, "issii" },
+	{ "imcb_chat_log", imcb_chat_log, rpc_imcb_chat_log, "is" },
+	{ "imcb_chat_topic", imcb_chat_topic, rpc_imcb_chat_topic, "issi" },
+	{ "imcb_chat_add_buddy", imcb_chat_add_buddy, rpc_imcb_chat_name_hint, "is" },
+	{ "imcb_chat_remove_buddy", imcb_chat_remove_buddy, rpc_imcb_chat_remove_buddy, "iss" },
+	{ "imcb_chat_invite", imcb_chat_invite, rpc_imcb_chat_invite, "isss" },
 
 	/* These are not imcb* functions but should still be exported. */
@@ -722,5 +720,5 @@
 			if (json_array_get_count(params) != strlen(methods[i].args)) {
 				imcb_error(ic, "Invalid argument count to method %s: %d, wanted %zd", cmd, (int) json_array_get_count(params), strlen(methods[i].args));
-				return jsonrpc_error(E2BIG, "Invalid number of arguments");
+				return jsonrpc_error(E2BIG, "Invalid integer of arguments");
 			}
 			int j;
@@ -732,6 +730,6 @@
 					ok = type == JSONString || type == JSONNull;
 					break;
-				case 'n':
-					ok = type == JSONNumber;
+				case 'i':
+					ok = type == JSONInteger;
 					break;
 				case 'o':
@@ -758,6 +756,8 @@
 
 #define RPC_ADD_FUNC(func) \
+	ret->func = rpc_ ## func
+#define RPC_ADD_OPT_FUNC(func) \
 	if (g_hash_table_contains(methods, #func)) \
-	 	ret->func = rpc_ ## func
+		RPC_ADD_FUNC(func)
 
 static JSON_Value *rpc_init_isup() {
@@ -767,5 +767,5 @@
 	JSON_Value *d = json_value_init_object();
 	json_object_set_string(json_object(d), "version_str", BITLBEE_VERSION);
-	json_object_set_number(json_object(d), "version", BITLBEE_VERSION_CODE);
+	json_object_set_integer(json_object(d), "version", BITLBEE_VERSION_CODE);
 	
 	JSON_Value *ml = json_value_init_array();
@@ -854,5 +854,5 @@
 	ret->data = proto_data;
 
-	proto_data->account_flags = json_object_get_number(isup, "account_flags");
+	proto_data->account_flags = json_object_get_integer(isup, "account_flags");
 
 	/* Keep a full copy of the settings list, we can only use it when we
@@ -878,23 +878,23 @@
 	ret->init = rpc_init;
 	RPC_ADD_FUNC(login);
-	RPC_ADD_FUNC(keepalive);
+	RPC_ADD_OPT_FUNC(keepalive);
 	RPC_ADD_FUNC(logout);
 	RPC_ADD_FUNC(buddy_msg);
-	RPC_ADD_FUNC(set_away);
-	RPC_ADD_FUNC(send_typing);
-	RPC_ADD_FUNC(add_buddy);
+	RPC_ADD_OPT_FUNC(set_away);
+	RPC_ADD_OPT_FUNC(send_typing);
+	RPC_ADD_FUNC(add_buddy);     /* Consider making these two optional? */
 	RPC_ADD_FUNC(remove_buddy);
-	RPC_ADD_FUNC(add_permit);
-	RPC_ADD_FUNC(add_deny);
-	RPC_ADD_FUNC(rem_permit);
-	RPC_ADD_FUNC(rem_deny);
-	RPC_ADD_FUNC(get_info);
-	RPC_ADD_FUNC(chat_invite);
-	RPC_ADD_FUNC(chat_kick);
-	RPC_ADD_FUNC(chat_leave);
-	RPC_ADD_FUNC(chat_msg);
-	RPC_ADD_FUNC(chat_with);
-	RPC_ADD_FUNC(chat_join);
-	RPC_ADD_FUNC(chat_topic);
+	RPC_ADD_OPT_FUNC(add_permit);
+	RPC_ADD_OPT_FUNC(add_deny);
+	RPC_ADD_OPT_FUNC(rem_permit);
+	RPC_ADD_OPT_FUNC(rem_deny);
+	RPC_ADD_OPT_FUNC(get_info);
+	RPC_ADD_OPT_FUNC(chat_invite);
+	RPC_ADD_OPT_FUNC(chat_kick);
+	RPC_ADD_OPT_FUNC(chat_leave);
+	RPC_ADD_OPT_FUNC(chat_msg);
+	RPC_ADD_OPT_FUNC(chat_with);
+	RPC_ADD_OPT_FUNC(chat_join);
+	RPC_ADD_OPT_FUNC(chat_topic);
 	if (proto_data->away_states)
 		ret->away_states = rpc_away_states;
