aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmatrix.c44
-rw-r--r--libmatrix.h3
-rw-r--r--matrix-json.c19
-rw-r--r--matrix-json.h3
-rw-r--r--matrix-login.c91
-rw-r--r--matrix-room.c2
6 files changed, 109 insertions, 53 deletions
diff --git a/libmatrix.c b/libmatrix.c
index f386f8d..51b057b 100644
--- a/libmatrix.c
+++ b/libmatrix.c
@@ -59,19 +59,6 @@ typedef struct {
} GcFuncData;
/*
- * stores offline messages that haven't been delivered yet. maps username
- * (char *) to GList * of GOfflineMessages. initialized in matrixprpl_init.
- */
-GHashTable* goffline_messages = NULL;
-
-typedef struct {
- char *from;
- char *message;
- time_t mtime;
- PurpleMessageFlags flags;
-} GOfflineMessage;
-
-/*
* helpers
*/
static PurpleConnection *get_matrixprpl_gc(const char *username) {
@@ -315,10 +302,7 @@ static int matrixprpl_send_im(PurpleConnection *gc, const char *who,
const char *message, PurpleMessageFlags flags)
{
const char *from_username = gc->account->username;
- PurpleMessageFlags receive_flags = ((flags & ~PURPLE_MESSAGE_SEND)
- | PURPLE_MESSAGE_RECV);
PurpleAccount *to_acct = purple_accounts_find(who, PRPL_ID);
- PurpleConnection *to;
purple_debug_info("matrixprpl", "sending message from %s to %s: %s\n",
from_username, who, message);
@@ -335,28 +319,6 @@ static int matrixprpl_send_im(PurpleConnection *gc, const char *who,
return 0;
}
- /* is the recipient online? */
- to = get_matrixprpl_gc(who);
- if (to) { /* yes, send */
- serv_got_im(to, from_username, message, receive_flags, time(NULL));
-
- } else { /* nope, store as an offline message */
- GOfflineMessage *offline_message;
- GList *messages;
-
- purple_debug_info("matrixprpl",
- "%s is offline, sending as offline message\n", who);
- offline_message = g_new0(GOfflineMessage, 1);
- offline_message->from = g_strdup(from_username);
- offline_message->message = g_strdup(message);
- offline_message->mtime = time(NULL);
- offline_message->flags = receive_flags;
-
- messages = g_hash_table_lookup(goffline_messages, who);
- messages = g_list_append(messages, offline_message);
- g_hash_table_insert(goffline_messages, g_strdup(who), messages);
- }
-
return 1;
}
@@ -1056,12 +1018,6 @@ static void matrixprpl_init(PurplePlugin *plugin)
"msg <username> <message>: send a private message, aka a whisper",
NULL); /* userdata */
- /* get ready to store offline messages */
- goffline_messages = g_hash_table_new_full(g_str_hash, /* hash fn */
- g_str_equal, /* key comparison fn */
- g_free, /* key free fn */
- NULL); /* value free fn */
-
_matrix_protocol = plugin;
}
diff --git a/libmatrix.h b/libmatrix.h
index 16eb403..0024348 100644
--- a/libmatrix.h
+++ b/libmatrix.h
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
- */
+ */
#ifndef LIBMATRIX_H
#define LIBMATRIX_H
@@ -37,7 +37,6 @@ typedef struct _MatrixAccount {
struct _PurpleConnection *pc;
gchar *homeserver; /* hostname (:port) of the homeserver */
gchar *access_token; /* access token corresponding to our user */
- GList rooms; /* a list of MatrixRooms */
} MatrixAccount;
#endif
diff --git a/matrix-json.c b/matrix-json.c
index 3cf6d0c..967441e 100644
--- a/matrix-json.c
+++ b/matrix-json.c
@@ -31,6 +31,16 @@ const gchar *matrix_json_node_get_string(JsonNode *node)
return json_node_get_string(node);
}
+gint64 matrix_json_node_get_int(JsonNode *node)
+{
+ if(node == NULL)
+ return 0;
+ if(JSON_NODE_TYPE(node) != JSON_NODE_VALUE)
+ return 0;
+ return json_node_get_int(node);
+}
+
+
JsonObject *matrix_json_node_get_object (JsonNode *node)
{
if(node == NULL)
@@ -72,6 +82,15 @@ const gchar *matrix_json_object_get_string_member(JsonObject *object,
return matrix_json_node_get_string(member);
}
+gint64 matrix_json_object_get_int_member(JsonObject *object,
+ const gchar *member_name)
+{
+ JsonNode *member;
+ member = matrix_json_object_get_member(object, member_name);
+ return matrix_json_node_get_int(member);
+}
+
+
JsonObject *matrix_json_object_get_object_member(JsonObject *object,
const gchar *member_name)
{
diff --git a/matrix-json.h b/matrix-json.h
index 0d2d97a..c789a1c 100644
--- a/matrix-json.h
+++ b/matrix-json.h
@@ -31,6 +31,7 @@
/* node - returns NULL if node == NULL or *node is of the wrong type */
const gchar *matrix_json_node_get_string(JsonNode *node);
+gint64 matrix_json_node_get_int(JsonNode *node);
JsonObject *matrix_json_node_get_object(JsonNode *node);
JsonArray *matrix_json_node_get_array(JsonNode *node);
@@ -42,6 +43,8 @@ JsonNode *matrix_json_object_get_member(JsonObject *object,
const gchar *member_name);
const gchar *matrix_json_object_get_string_member(JsonObject *object,
const gchar *member_name);
+gint64 matrix_json_object_get_int_member(JsonObject *object,
+ const gchar *member_name);
JsonObject *matrix_json_object_get_object_member(JsonObject *object,
const gchar *member_name);
JsonArray *matrix_json_object_get_array_member(JsonObject *object,
diff --git a/matrix-login.c b/matrix-login.c
index de1654b..1a48e38 100644
--- a/matrix-login.c
+++ b/matrix-login.c
@@ -36,14 +36,89 @@
/* TODO: make this configurable */
#define MATRIX_HOMESERVER "www.sw1v.org"
+/* TODO: move this out */
+typedef struct _RoomEventParserData {
+ MatrixAccount *acct;
+ const gchar *room_id;
+ JsonObject *event_map;
+} RoomEventParserData;
+
+static void parse_timeline_event(JsonArray *timeline,
+ guint state_idx, JsonNode *timeline_entry, gpointer user_data)
+{
+ RoomEventParserData *data = user_data;
+ MatrixAccount *ma = data->acct;
+ JsonObject *event_map = data->event_map;
+ const gchar *room_id = data->room_id;
+ const gchar *event_id, *event_type, *msg_body, *sender;
+ JsonObject *json_event_obj, *json_content_obj;
+ PurpleMessageFlags flags;
+ gint64 timestamp;
+
+ event_id = matrix_json_node_get_string(timeline_entry);
+ if(event_id == NULL) {
+ purple_debug_warning("prplmatrix", "non-string event_id");
+ return;
+ }
+
+ json_event_obj = matrix_json_object_get_object_member(
+ event_map, event_id);
+ if(json_event_obj == NULL) {
+ purple_debug_warning("prplmatrix", "unknown event_id %s", event_id);
+ return;
+ }
+
+ event_type = matrix_json_object_get_string_member(
+ json_event_obj, "type");
+ json_content_obj = matrix_json_object_get_object_member(
+ json_event_obj, "content");
+ if(event_type == NULL || json_content_obj == NULL)
+ return;
+
+ if(strcmp(event_type, "m.room.message") != 0) {
+ purple_debug_info("prplmatrix", "ignoring unknown room event %s",
+ event_type);
+ return;
+ }
+
+ msg_body = matrix_json_object_get_string_member(json_content_obj, "body");
+ if(msg_body == NULL) {
+ purple_debug_warning("prplmatrix", "no body in message event %s",
+ event_id);
+ return;
+ }
+
+ sender = matrix_json_object_get_string_member(json_event_obj, "sender");
+ if(sender == NULL) {
+ sender = "<unknown>";
+ }
+
+ timestamp = matrix_json_object_get_int_member(json_event_obj,
+ "origin_server_ts");
+
+ flags = PURPLE_MESSAGE_RECV;
+
+ purple_debug_info("prplmatrix", "got message %s in %s\n", msg_body, room_id);
+ serv_got_chat_in(ma->pc, g_str_hash(room_id), sender, flags,
+ msg_body, timestamp / 1000);
+}
+
+static void parse_timeline_events(MatrixAccount *acct,
+ const gchar *room_id,
+ JsonArray *events, JsonObject* event_map)
+{
+ RoomEventParserData data = {acct, room_id, event_map};
+ json_array_foreach_element(events, parse_timeline_event, &data);
+}
+
/**
* handle a room within the initial sync response
*/
static void matrixprpl_handle_initial_sync_room(
const gchar *room_id, JsonObject *room_data, MatrixAccount *ma)
{
- JsonObject *state_object, *event_map;
- JsonArray *state_array;
+ JsonObject *state_object, *timeline_object, *event_map;
+ JsonArray *state_array, *timeline_array;
const gchar *room_name;
PurpleConversation *conv;
PurpleChat *chat;
@@ -51,11 +126,11 @@ static void matrixprpl_handle_initial_sync_room(
MatrixRoomStateEventTable *state_table;
event_map = matrix_json_object_get_object_member(room_data, "event_map");
- state_object = matrix_json_object_get_object_member(room_data, "state");
- state_array = matrix_json_object_get_array_member(state_object, "events");
/* parse the room state */
state_table = g_hash_table_new(g_str_hash, g_str_equal); /* TODO: free */
+ state_object = matrix_json_object_get_object_member(room_data, "state");
+ state_array = matrix_json_object_get_array_member(state_object, "events");
if(state_array != NULL)
matrix_room_parse_state_events(state_table, state_array, event_map);
@@ -87,6 +162,12 @@ static void matrixprpl_handle_initial_sync_room(
conv = serv_got_joined_chat(ma->pc, g_str_hash(room_id), room_id);
purple_conversation_set_data(conv, "room_id", g_strdup(room_id)); /* TODO: free */
purple_conversation_set_data(conv, "state", state_table);
+
+ timeline_object = matrix_json_object_get_object_member(
+ room_data, "timeline");
+ timeline_array = matrix_json_object_get_array_member(
+ timeline_object, "events");
+ parse_timeline_events(ma, room_id, timeline_array, event_map);
}
@@ -174,7 +255,7 @@ static void matrixprpl_sync_complete(MatrixAccount *ma,
}
purple_connection_update_progress(ma->pc, _("Connected"), 2, 3);
- purple_connection_set_state(ma->pc, PURPLE_CONNECTED);
+ purple_connection_set_state(ma->pa->gc, PURPLE_CONNECTED);
matrixprpl_handle_initial_sync(ma, body);
}
diff --git a/matrix-room.c b/matrix-room.c
index a4fe75d..bb519a0 100644
--- a/matrix-room.c
+++ b/matrix-room.c
@@ -155,8 +155,6 @@ GList *matrixprpl_chat_info(PurpleConnection *gc)
{
struct proto_chat_entry *pce; /* defined in prpl.h */
- purple_debug_info("matrixprpl", "returning chat setting 'room_id'\n");
-
pce = g_new0(struct proto_chat_entry, 1);
pce->label = _("Chat _room");
pce->identifier = "room_id";