1
1
mirror of https://github.com/profanity-im/profanity.git synced 2025-01-03 14:57:42 -05:00

Implemented /room kick command

This commit is contained in:
James Booth 2014-10-05 20:52:34 +01:00
parent ac7bc02c63
commit d12534c58e
8 changed files with 334 additions and 31 deletions

View File

@ -490,6 +490,7 @@ void
handle_leave_room(const char * const room)
{
muc_leave(room);
ui_leave_room(room);
}
void
@ -511,7 +512,22 @@ void
handle_room_destroy(const char * const room)
{
muc_leave(room);
ui_room_destroyed(room);
ui_room_destroy(room);
}
void
handle_room_destroyed(const char * const room, const char * const new_jid, const char * const password,
const char * const reason)
{
muc_leave(room);
ui_room_destroyed(room, reason, new_jid, password);
}
void
handle_room_kicked(const char * const room, const char * const actor, const char * const reason)
{
muc_leave(room);
ui_room_kicked(room, actor, reason);
}
void
@ -538,12 +554,6 @@ handle_room_config_submit_result_error(const char * const room, const char * con
ui_handle_room_config_submit_result_error(room, message);
}
void
handle_room_kick(const char * const room, const char * const nick)
{
ui_handle_room_kick(room, nick);
}
void
handle_room_kick_result_error(const char * const room, const char * const nick, const char * const error)
{
@ -619,6 +629,15 @@ handle_room_member_offline(const char * const room, const char * const nick,
prefs_free_string(muc_status_pref);
}
void
handle_room_occupent_kicked(const char * const room, const char * const nick, const char * const actor,
const char * const reason)
{
muc_roster_remove(room, nick);
ui_room_member_kicked(room, nick, actor, reason);
}
void
handle_room_member_nick_change(const char * const room,
const char * const old_nick, const char * const nick)

View File

@ -65,7 +65,6 @@ void handle_room_affiliation_list(const char * const room, const char * const af
void handle_room_affiliation_set_error(const char * const room, const char * const jid, const char * const affiliation,
const char * const error);
void handle_room_affiliation_set(const char * const room, const char * const jid, const char * const affiliation);
void handle_room_kick(const char * const room, const char * const nick);
void handle_room_kick_result_error(const char * const room, const char * const nick, const char * const error);
void handle_duck_result(const char * const result);
void handle_incoming_message(char *from, char *message, gboolean priv);
@ -91,6 +90,11 @@ void handle_room_member_offline(const char * const room, const char * const nick
const char * const show, const char * const status);
void handle_room_member_nick_change(const char * const room,
const char * const old_nick, const char * const nick);
void handle_room_destroyed(const char * const room, const char * const new_jid, const char * const password,
const char * const reason);
void handle_room_kicked(const char * const room, const char * const actor, const char * const reason);
void handle_room_occupent_kicked(const char * const room, const char * const nick, const char * const actor,
const char * const reason);
void handle_group_add(const char * const contact,
const char * const group);
void handle_group_remove(const char * const contact,

View File

@ -1493,6 +1493,31 @@ _ui_room_member_offline(const char * const room, const char * const nick)
}
}
static void
_ui_room_member_kicked(const char * const room, const char * const nick, const char * const actor,
const char * const reason)
{
ProfWin *window = wins_get_by_recipient(room);
if (window == NULL) {
log_error("Received kick for room participant %s, but no window open for %s.", nick, room);
} else {
GString *message = g_string_new(nick);
g_string_append(message, " has been kicked from the room");
if (actor) {
g_string_append(message, " by ");
g_string_append(message, actor);
}
if (reason) {
g_string_append(message, ", reason: ");
g_string_append(message, reason);
}
win_save_vprint(window, '!', NULL, 0, COLOUR_OFFLINE, "", "<- %s", message->str);
g_string_free(message, TRUE);
}
}
static void
_ui_room_member_online(const char * const room, const char * const nick,
const char * const show, const char * const status)
@ -1691,7 +1716,7 @@ _ui_room_requires_config(const char * const room_jid)
}
static void
_ui_room_destroyed(const char * const room_jid)
_ui_room_destroy(const char * const room_jid)
{
ProfWin *window = wins_get_by_recipient(room_jid);
if (window == NULL) {
@ -1703,6 +1728,71 @@ _ui_room_destroyed(const char * const room_jid)
}
}
static void
_ui_leave_room(const char * const room)
{
ProfWin *window = wins_get_by_recipient(room);
if (window) {
int num = wins_get_num(window);
ui_close_win(num);
}
}
static void
_ui_room_destroyed(const char * const room, const char * const reason, const char * const new_jid,
const char * const password)
{
ProfWin *window = wins_get_by_recipient(room);
if (window == NULL) {
log_error("Received room destroy, but no window open for %s.", room);
} else {
int num = wins_get_num(window);
ui_close_win(num);
ProfWin *console = wins_get_console();
if (reason) {
win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "<- Room destroyed: %s, reason: %s", room, reason);
} else {
win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "<- Room destroyed: %s", room);
}
if (new_jid) {
if (password) {
win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "Replacement room: %s, password: %s", new_jid, password);
} else {
win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "Replacement room: %s", new_jid);
}
}
}
}
static void
_ui_room_kicked(const char * const room, const char * const actor, const char * const reason)
{
ProfWin *window = wins_get_by_recipient(room);
if (window == NULL) {
log_error("Received kick, but no window open for %s.", room);
} else {
int num = wins_get_num(window);
ui_close_win(num);
GString *message = g_string_new("Kicked from ");
g_string_append(message, room);
if (actor) {
g_string_append(message, " by ");
g_string_append(message, actor);
}
if (reason) {
g_string_append(message, ", reason: ");
g_string_append(message, reason);
}
ProfWin *console = wins_get_console();
win_save_vprint(console, '!', NULL, 0, COLOUR_TYPING, "", "<- %s", message->str);
g_string_free(message, TRUE);
}
}
static void
_ui_room_subject(const char * const room, const char * const nick, const char * const subject)
{
@ -1750,17 +1840,6 @@ _ui_handle_room_kick_error(const char * const room, const char * const nick, con
}
}
static void
_ui_handle_room_kick(const char * const room, const char * const nick)
{
ProfWin *window = wins_get_by_recipient(room);
if (window == NULL) {
log_error("Kick result received for %s, but no window open for %s.", nick, room);
} else {
win_save_vprint(window, '!', NULL, 0, 0, "", "%s has been kicked from the room", nick);
}
}
static void
_ui_room_broadcast(const char * const room_jid, const char * const message)
{
@ -2766,7 +2845,7 @@ ui_init_module(void)
ui_swap_wins = _ui_swap_wins;
ui_update = _ui_update;
ui_room_requires_config = _ui_room_requires_config;
ui_room_destroyed = _ui_room_destroyed;
ui_room_destroy = _ui_room_destroy;
ui_handle_room_configuration = _ui_handle_room_configuration;
ui_handle_room_config_submit_result = _ui_handle_room_config_submit_result;
ui_handle_room_config_submit_result_error = _ui_handle_room_config_submit_result_error;
@ -2783,9 +2862,13 @@ ui_init_module(void)
ui_handle_room_info_error = _ui_handle_room_info_error;
ui_show_room_disco_info = _ui_show_room_disco_info;
ui_handle_room_affiliation_list_error = _ui_handle_room_affiliation_list_error;
ui_handle_room_affiliation_list =_ui_handle_room_affiliation_list;
ui_handle_room_affiliation_set_error =_ui_handle_room_affiliation_set_error;
ui_handle_room_affiliation_list = _ui_handle_room_affiliation_list;
ui_handle_room_affiliation_set_error = _ui_handle_room_affiliation_set_error;
ui_handle_room_affiliation_set = _ui_handle_room_affiliation_set;
ui_handle_room_kick_error =_ui_handle_room_kick_error;
ui_handle_room_kick = _ui_handle_room_kick;
ui_handle_room_kick_error = _ui_handle_room_kick_error;
ui_room_destroyed = _ui_room_destroyed;
ui_room_kicked = _ui_room_kicked;
ui_leave_room = _ui_leave_room;
ui_room_member_kicked = _ui_room_member_kicked;
}

View File

@ -135,13 +135,18 @@ void (*ui_room_message)(const char * const room_jid, const char * const nick,
const char * const message);
void (*ui_room_subject)(const char * const room, const char * const nick, const char * const subject);
void (*ui_room_requires_config)(const char * const room_jid);
void (*ui_room_destroyed)(const char * const room_jid);
void (*ui_room_destroy)(const char * const room_jid);
void (*ui_show_room_info)(ProfWin *window, const char * const room);
void (*ui_show_room_role_list)(ProfWin *window, const char * const room, muc_role_t role);
void (*ui_show_room_affiliation_list)(ProfWin *window, const char * const room, muc_affiliation_t affiliation);
void (*ui_handle_room_info_error)(const char * const room, const char * const error);
void (*ui_show_room_disco_info)(const char * const room, GSList *identities, GSList *features);
void (*ui_room_destroyed)(const char * const room, const char * const reason, const char * const new_jid,
const char * const password);
void (*ui_room_kicked)(const char * const room, const char * const actor, const char * const reason);
void (*ui_room_member_kicked)(const char * const room, const char * const nick, const char * const actor,
const char * const reason);
void (*ui_leave_room)(const char * const room);
void (*ui_room_broadcast)(const char * const room_jid,
const char * const message);
void (*ui_room_member_offline)(const char * const room, const char * const nick);
@ -176,7 +181,6 @@ void (*ui_handle_room_affiliation_set_error)(const char * const room, const char
const char * const affiliation, const char * const error);
void (*ui_handle_room_affiliation_set)(const char * const room, const char * const jid, const char * const affiliation);
void (*ui_handle_room_kick_error)(const char * const room, const char * const nick, const char * const error);
void (*ui_handle_room_kick)(const char * const room, const char * const nick);
void (*ui_show_form)(ProfWin *window, const char * const room, DataForm *form);
void (*ui_show_form_field)(ProfWin *window, DataForm *form, char *tag);
void (*ui_show_form_help)(ProfWin *window, DataForm *form);

View File

@ -960,7 +960,6 @@ _room_kick_result_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza
return 0;
}
handle_room_kick(from, nick);
free(nick);
return 0;

View File

@ -704,7 +704,30 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
if (new_nick != NULL) {
muc_nick_change_start(from_room, new_nick);
} else {
handle_leave_room(from_room);
GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER);
// room destroyed
if (stanza_room_destroyed(stanza)) {
char *new_jid = stanza_get_muc_destroy_alternative_room(stanza);
char *password = stanza_get_muc_destroy_alternative_password(stanza);
char *reason = stanza_get_muc_destroy_reason(stanza);
handle_room_destroyed(from_room, new_jid, password, reason);
free(password);
free(reason);
// kicked from room
} else if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
char *actor = stanza_get_kick_actor(stanza);
char *reason = stanza_get_kick_reason(stanza);
handle_room_kicked(from_room, actor, reason);
free(reason);
// normal exit
} else {
handle_leave_room(from_room);
}
g_slist_free(status_codes);
}
// self online
@ -756,7 +779,19 @@ _muc_user_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
free(new_nick);
}
} else {
handle_room_member_offline(from_room, from_nick, "offline", status_str);
GSList *status_codes = stanza_get_status_codes_by_ns(stanza, STANZA_NS_MUC_USER);
// kicked from room
if (g_slist_find_custom(status_codes, "307", (GCompareFunc)g_strcmp0) != NULL) {
char *actor = stanza_get_kick_actor(stanza);
char *reason = stanza_get_kick_reason(stanza);
handle_room_occupent_kicked(from_room, from_nick, actor, reason);
free(reason);
// normal exit
} else {
handle_room_member_offline(from_room, from_nick, "offline", status_str);
}
}
} else {
// send disco info for capabilities, if not cached

View File

@ -1010,6 +1010,156 @@ stanza_is_muc_self_presence(xmpp_stanza_t * const stanza,
return FALSE;
}
GSList *
stanza_get_status_codes_by_ns(xmpp_stanza_t * const stanza, char *ns)
{
GSList *codes = NULL;
xmpp_stanza_t *ns_child = xmpp_stanza_get_child_by_ns(stanza, ns);
if (ns_child) {
xmpp_stanza_t *child = xmpp_stanza_get_children(ns_child);
while (child) {
char *name = xmpp_stanza_get_name(child);
if (g_strcmp0(name, STANZA_NAME_STATUS) == 0) {
char *code = xmpp_stanza_get_attribute(child, STANZA_ATTR_CODE);
if (code) {
codes = g_slist_append(codes, code);
}
}
child = xmpp_stanza_get_next(child);
}
}
return codes;
}
gboolean
stanza_room_destroyed(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY);
if (destroy) {
return TRUE;
}
}
}
return FALSE;
}
char *
stanza_get_muc_destroy_alternative_room(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY);
if (destroy) {
char *jid = xmpp_stanza_get_attribute(destroy, STANZA_ATTR_JID);
if (jid) {
return jid;
}
}
}
}
return NULL;
}
char *
stanza_get_muc_destroy_alternative_password(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY);
if (destroy) {
xmpp_stanza_t *password_st = xmpp_stanza_get_child_by_name(destroy, STANZA_NAME_PASSWORD);
if (password_st) {
char *password = xmpp_stanza_get_text(password_st);
if (password) {
return password;
}
}
}
}
}
return NULL;
}
char *
stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *destroy = xmpp_stanza_get_child_by_name(x, STANZA_NAME_DESTROY);
if (destroy) {
xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(destroy, STANZA_NAME_REASON);
if (reason_st) {
char *reason = xmpp_stanza_get_text(reason_st);
if (reason) {
return reason;
}
}
}
}
}
return NULL;
}
char *
stanza_get_kick_actor(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM);
if (item) {
xmpp_stanza_t *actor = xmpp_stanza_get_child_by_name(item, STANZA_NAME_ACTOR);
if (actor) {
char *nick = xmpp_stanza_get_attribute(actor, STANZA_ATTR_NICK);
if (nick) {
return nick;
}
char *jid = xmpp_stanza_get_attribute(actor, STANZA_ATTR_JID);
if (jid) {
return jid;
}
}
}
}
}
return NULL;
}
char *
stanza_get_kick_reason(xmpp_stanza_t *stanza)
{
char *stanza_name = xmpp_stanza_get_name(stanza);
if (g_strcmp0(stanza_name, STANZA_NAME_PRESENCE) == 0) {
xmpp_stanza_t *x = xmpp_stanza_get_child_by_ns(stanza, STANZA_NS_MUC_USER);
if (x) {
xmpp_stanza_t *item = xmpp_stanza_get_child_by_name(x, STANZA_NAME_ITEM);
if (item) {
xmpp_stanza_t *reason_st = xmpp_stanza_get_child_by_name(item, STANZA_NAME_REASON);
if (reason_st) {
char *reason = xmpp_stanza_get_text(reason_st);
if (reason) {
return reason;
}
}
}
}
}
return NULL;
}
gboolean
stanza_is_room_nick_change(xmpp_stanza_t * const stanza)
{

View File

@ -76,6 +76,7 @@
#define STANZA_NAME_CONFERENCE "conference"
#define STANZA_NAME_VALUE "value"
#define STANZA_NAME_DESTROY "destroy"
#define STANZA_NAME_ACTOR "actor"
// error conditions
#define STANZA_NAME_BAD_REQUEST "bad-request"
@ -248,4 +249,12 @@ xmpp_stanza_t * stanza_create_roster_remove_set(xmpp_ctx_t *ctx,
char * stanza_get_error_message(xmpp_stanza_t * const stanza);
GSList* stanza_get_status_codes_by_ns(xmpp_stanza_t * const stanza, char *ns);
gboolean stanza_room_destroyed(xmpp_stanza_t *stanza);
char* stanza_get_muc_destroy_alternative_room(xmpp_stanza_t *stanza);
char* stanza_get_muc_destroy_alternative_password(xmpp_stanza_t *stanza);
char* stanza_get_muc_destroy_reason(xmpp_stanza_t *stanza);
char* stanza_get_kick_actor(xmpp_stanza_t *stanza);
char* stanza_get_kick_reason(xmpp_stanza_t *stanza);
#endif