Per-channel sync
Discord no longer seems to support per-guild sync, but per-channel sync was added. Switch to that syncing user lists on channel join. Fixes: #201 Signed-off-by: Artem Savkov <artem.savkov@gmail.com>
This commit is contained in:
parent
6500934bba
commit
1b9870a0ea
|
@ -800,6 +800,28 @@ void discord_handle_message(struct im_connection *ic, json_value *minfo,
|
|||
}
|
||||
}
|
||||
|
||||
static void parse_list_update_item(struct im_connection *ic,
|
||||
const char *guild_id, const char *op,
|
||||
json_value *item)
|
||||
{
|
||||
discord_data *dd = ic->proto_data;
|
||||
json_value *member = json_o_get(item, "member");
|
||||
json_value *uinfo = json_o_get(member, "user");
|
||||
json_value *pinfo = json_o_get(member, "presence");
|
||||
|
||||
if (g_strcmp0(op, "DELETE") == 0) {
|
||||
discord_handle_user(ic, uinfo, guild_id, ACTION_DELETE);
|
||||
} else {
|
||||
user_info *user = get_user(dd, json_o_str(uinfo, "id"), guild_id,
|
||||
SEARCH_ID);
|
||||
if (user == NULL) {
|
||||
discord_handle_user(ic, uinfo, guild_id, ACTION_CREATE);
|
||||
}
|
||||
|
||||
discord_handle_presence(ic, pinfo, guild_id);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean discord_parse_message(struct im_connection *ic, gchar *buf, guint64 size)
|
||||
{
|
||||
discord_data *dd = ic->proto_data;
|
||||
|
@ -944,6 +966,33 @@ gboolean discord_parse_message(struct im_connection *ic, gchar *buf, guint64 siz
|
|||
discord_handle_presence(ic, pinfo, id);
|
||||
}
|
||||
}
|
||||
} else if (g_strcmp0(event, "GUILD_MEMBER_LIST_UPDATE") == 0) {
|
||||
json_value *data = json_o_get(js, "d");
|
||||
json_value *ops = json_o_get(data, "ops");
|
||||
const char *guild_id = json_o_str(data, "guild_id");
|
||||
|
||||
if (ops != NULL && ops->type == json_array) {
|
||||
for (int oidx = 0; oidx < ops->u.array.length; oidx++) {
|
||||
const char *op = json_o_str(ops->u.array.values[oidx], "op");
|
||||
|
||||
if (g_strcmp0(op, "SYNC") == 0) {
|
||||
json_value *items = json_o_get(ops->u.array.values[oidx], "items");
|
||||
if (items != NULL && items->type == json_array) {
|
||||
for (int iidx = 0; iidx < items->u.array.length; iidx++) {
|
||||
json_value *item = items->u.array.values[iidx];
|
||||
if (item != NULL && json_o_get(item, "member") != NULL) {
|
||||
parse_list_update_item(ic, guild_id, op, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
json_value *item = json_o_get(ops->u.array.values[oidx], "item");
|
||||
if (item != NULL && json_o_get(item, "member") != NULL) {
|
||||
parse_list_update_item(ic, guild_id, op, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (g_strcmp0(event, "VOICE_STATE_UPDATE") == 0) {
|
||||
json_value *vsinfo = json_o_get(js, "d");
|
||||
discord_handle_voice_state(ic, vsinfo, json_o_str(vsinfo, "guild_id"));
|
||||
|
|
|
@ -98,6 +98,16 @@ void discord_ws_sync_server(discord_data *dd, const char *id)
|
|||
g_string_free(buf, TRUE);
|
||||
}
|
||||
|
||||
void discord_ws_sync_channel(discord_data *dd, const char *guild_id,
|
||||
const char *channel_id, unsigned int members)
|
||||
{
|
||||
GString *buf = g_string_new("");
|
||||
g_string_printf(buf, "{\"op\":%d,\"d\":{\"guild_id\":\"%s\",\"typing\":true,\"activities\":true,\"channels\":{\"%s\":[[0,%u]]}}}",
|
||||
OPCODE_REQUEST_SYNC_CHANNEL, guild_id, channel_id, members);
|
||||
discord_ws_send_payload(dd, buf->str, buf->len);
|
||||
g_string_free(buf, TRUE);
|
||||
}
|
||||
|
||||
static gboolean discord_ws_heartbeat_timeout(gpointer data, gint fd,
|
||||
b_input_condition cond)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,9 @@ typedef enum {
|
|||
OPCODE_INVALID_SESSION,
|
||||
OPCODE_HELLO,
|
||||
OPCODE_HEARTBEAT_ACK,
|
||||
OPCODE_REQUEST_SYNC
|
||||
OPCODE_REQUEST_SYNC,
|
||||
OPCODE_UNKNOWN,
|
||||
OPCODE_REQUEST_SYNC_CHANNEL
|
||||
} discord_opcode;
|
||||
|
||||
gboolean discord_ws_keepalive_loop(gpointer data, gint fd,
|
||||
|
@ -40,3 +42,5 @@ void discord_ws_cleanup(discord_data *dd);
|
|||
void discord_ws_set_status(struct im_connection *ic, gchar *status,
|
||||
gchar *message);
|
||||
void discord_ws_sync_server(discord_data *dd, const char *id);
|
||||
void discord_ws_sync_channel(discord_data *dd, const char *guild_id,
|
||||
const char *channel_id, unsigned int members);
|
||||
|
|
|
@ -195,6 +195,7 @@ struct groupchat *discord_chat_do_join(struct im_connection *ic,
|
|||
if (cinfo != NULL && cinfo->type == CHANNEL_TEXT) {
|
||||
sinfo = cinfo->to.channel.sinfo;
|
||||
gc = imcb_chat_new(ic, cinfo->to.channel.name);
|
||||
discord_ws_sync_channel(dd, sinfo->id, cinfo->id, 0);
|
||||
|
||||
if (is_auto_join) {
|
||||
imcb_chat_name_hint(gc, room);
|
||||
|
|
Loading…
Reference in New Issue