863 lines
20 KiB
C
863 lines
20 KiB
C
#include <strings.h>
|
|
#include <string.h>
|
|
#include "gm-mcp-vmoo-userlist.h"
|
|
#include "gm-mcp-userlist-view.h"
|
|
#include "gm-iuserlist.h"
|
|
#include "gm-mcp-session.h"
|
|
#include "gm-mcp.h"
|
|
#include "gm-support.h"
|
|
#include "gm-marshal.h"
|
|
#include "gm-debug.h"
|
|
#include "gm-world.h"
|
|
#include "list.h"
|
|
|
|
#define GM_MCP_VMOO_USERLIST_GET_PRIVATE(object)( \
|
|
G_TYPE_INSTANCE_GET_PRIVATE((object), \
|
|
GM_TYPE_MCP_VMOO_USERLIST, GmMcpVmooUserlistPrivate))
|
|
|
|
static const GmKeyValuePair icon_mapping[] = {
|
|
{"newbie", "userlist/newbie.svg"},
|
|
{"inhabitant", "userlist/inhabitant.svg"},
|
|
{"inhabitant+", "userlist/inhabitantplus.svg"},
|
|
{"schooled", "userlist/schooled.svg"},
|
|
{"key", "userlist/key.svg"},
|
|
{"star", "userlist/star.svg"},
|
|
{"wizard", "userlist/wizard.svg"},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
typedef enum _UserState {
|
|
U_NORMAL,
|
|
U_AWAY,
|
|
U_IDLE,
|
|
U_IDLEAWAY
|
|
} UserState;
|
|
|
|
typedef struct _UserInfo {
|
|
gint nr;
|
|
guint icon;
|
|
gchar *name;
|
|
UserState state;
|
|
} UserInfo;
|
|
|
|
struct _GmMcpVmooUserlistPrivate {
|
|
gint you;
|
|
GList *fields;
|
|
GList *icons;
|
|
GList *users;
|
|
GList *menu;
|
|
gboolean initializing;
|
|
};
|
|
|
|
/* Signals */
|
|
|
|
enum {
|
|
PLAYER_ADDED,
|
|
PLAYER_REMOVED,
|
|
NAME_CHANGED,
|
|
STATE_CHANGED,
|
|
RANK_CHANGED,
|
|
NUM_SIGNALS
|
|
};
|
|
|
|
static void gm_mcp_vmoo_userlist_iface_init(GmIUserlistInterface *iface);
|
|
static guint gm_mcp_vmoo_userlist_signals[NUM_SIGNALS] = {0};
|
|
|
|
G_DEFINE_TYPE_EXTENDED(GmMcpVmooUserlist, gm_mcp_vmoo_userlist, \
|
|
GM_TYPE_MCP_PACKAGE, 0, G_IMPLEMENT_INTERFACE(GM_TYPE_IUSERLIST, \
|
|
gm_mcp_vmoo_userlist_iface_init))
|
|
|
|
void gm_mcp_vmoo_userlist_handle_simple(GmMcpPackage *package,
|
|
gchar *suffix, GList *fields);
|
|
gboolean gm_mcp_vmoo_userlist_handle_multi(GmMcpPackage *package,
|
|
gchar const *data_tag, gchar const *key, gchar const *value,
|
|
GList *all_values);
|
|
|
|
void gm_mcp_vmoo_userlist_create_view(GmMcpPackage *package,
|
|
GObject *parent);
|
|
GList *gm_mcp_vmoo_userlist_get_menu(GmIUserlist *userlist, gint id);
|
|
|
|
static void
|
|
gm_mcp_vmoo_userlist_iface_init(
|
|
GmIUserlistInterface *iface) {
|
|
iface->get_menu = gm_mcp_vmoo_userlist_get_menu;
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_remove_users(GmMcpVmooUserlist *package) {
|
|
GList *users = g_list_copy(package->priv->users);
|
|
GList *field;
|
|
UserInfo *info;
|
|
|
|
for (field = users; field; field = field->next) {
|
|
info = (UserInfo *)(field->data);
|
|
package->priv->users = g_list_remove(package->priv->users, field->data);
|
|
|
|
g_free(info->name);
|
|
g_free(info);
|
|
}
|
|
|
|
g_list_free(users);
|
|
}
|
|
|
|
static void
|
|
gm_mcp_vmoo_userlist_free_menu(GmMcpVmooUserlist *obj) {
|
|
GList *field;
|
|
GmKeyValuePair *pair;
|
|
|
|
for (field = obj->priv->menu; field; field = field->next) {
|
|
pair = (GmKeyValuePair *)(field->data);
|
|
|
|
g_free(pair->key);
|
|
g_free(pair->value);
|
|
g_free(pair);
|
|
}
|
|
|
|
obj->priv->menu = NULL;
|
|
}
|
|
|
|
static void
|
|
gm_mcp_vmoo_userlist_finalize(GObject *object) {
|
|
GmMcpVmooUserlist *obj = GM_MCP_VMOO_USERLIST(object);
|
|
GList *field;
|
|
|
|
for (field = obj->priv->fields; field; field = field->next) {
|
|
g_free(field->data);
|
|
}
|
|
|
|
g_list_free(obj->priv->fields);
|
|
|
|
for (field = obj->priv->icons; field; field = field->next) {
|
|
g_free(field->data);
|
|
}
|
|
|
|
g_list_free(obj->priv->icons);
|
|
|
|
gm_mcp_vmoo_userlist_free_menu(obj);
|
|
|
|
gm_mcp_vmoo_userlist_remove_users(obj);
|
|
g_list_free(obj->priv->users);
|
|
|
|
G_OBJECT_CLASS(gm_mcp_vmoo_userlist_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
gm_mcp_vmoo_userlist_class_init(GmMcpVmooUserlistClass *klass) {
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
|
|
|
|
object_class->finalize = gm_mcp_vmoo_userlist_finalize;
|
|
|
|
gm_mcp_vmoo_userlist_signals[PLAYER_ADDED] =
|
|
g_signal_new("player_added",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpVmooUserlistClass, player_added),
|
|
NULL, NULL,
|
|
gm_marshal_VOID__INT_STRING_STRING_STRING,
|
|
G_TYPE_NONE,
|
|
4,
|
|
G_TYPE_INT,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
gm_mcp_vmoo_userlist_signals[PLAYER_REMOVED] =
|
|
g_signal_new("player_removed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpVmooUserlistClass, player_removed),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__INT,
|
|
G_TYPE_NONE,
|
|
1,
|
|
G_TYPE_INT);
|
|
gm_mcp_vmoo_userlist_signals[NAME_CHANGED] =
|
|
g_signal_new("name_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpVmooUserlistClass, name_changed),
|
|
NULL, NULL,
|
|
gm_marshal_VOID__INT_STRING_STRING,
|
|
G_TYPE_NONE,
|
|
3,
|
|
G_TYPE_INT,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
gm_mcp_vmoo_userlist_signals[STATE_CHANGED] =
|
|
g_signal_new("state_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpVmooUserlistClass, state_changed),
|
|
NULL, NULL,
|
|
gm_marshal_VOID__INT_STRING_STRING,
|
|
G_TYPE_NONE,
|
|
3,
|
|
G_TYPE_INT,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
|
|
gm_mcp_vmoo_userlist_signals[RANK_CHANGED] =
|
|
g_signal_new("rank_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpVmooUserlistClass, rank_changed),
|
|
NULL, NULL,
|
|
gm_marshal_VOID__INT_STRING_STRING,
|
|
G_TYPE_NONE,
|
|
3,
|
|
G_TYPE_INT,
|
|
G_TYPE_STRING,
|
|
G_TYPE_STRING);
|
|
|
|
pklass->name = "dns-com-vmoo-userlist";
|
|
pklass->handle_simple = &gm_mcp_vmoo_userlist_handle_simple;
|
|
pklass->handle_multi = &gm_mcp_vmoo_userlist_handle_multi;
|
|
pklass->create_view = &gm_mcp_vmoo_userlist_create_view;
|
|
|
|
g_type_class_add_private(object_class, sizeof(GmMcpVmooUserlistPrivate));
|
|
}
|
|
|
|
static void
|
|
gm_mcp_vmoo_userlist_init(GmMcpVmooUserlist *obj) {
|
|
obj->priv = GM_MCP_VMOO_USERLIST_GET_PRIVATE(obj);
|
|
|
|
obj->priv->you = 0;
|
|
obj->priv->fields = NULL;
|
|
obj->priv->icons = NULL;
|
|
obj->priv->users = NULL;
|
|
}
|
|
|
|
GmMcpVmooUserlist *
|
|
gm_mcp_vmoo_userlist_new() {
|
|
GmMcpVmooUserlist *obj = GM_MCP_VMOO_USERLIST(g_object_new( \
|
|
GM_TYPE_MCP_VMOO_USERLIST, NULL));
|
|
|
|
return obj;
|
|
}
|
|
|
|
#define MAX_MATCHES 10
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_process_triggers(GmMcpVmooUserlist *package,
|
|
gchar const *username, GmTriggerConditionType condition) {
|
|
GmWorld *world;
|
|
GmTriggers *triggers;
|
|
GList const *item;
|
|
GmTrigger *trigger;
|
|
regmatch_t matches[MAX_MATCHES];
|
|
|
|
if (package->priv->initializing) {
|
|
return;
|
|
}
|
|
|
|
world = GM_MCP_SESSION_WORLD(GM_MCP_PACKAGE_SESSION(package));
|
|
triggers = gm_world_triggers(world);
|
|
|
|
for (item = gm_triggers_list(triggers); item; item = item->next) {
|
|
trigger = (GmTrigger *)(item->data);
|
|
|
|
if (trigger->event == TT_USERS) {
|
|
if (gm_trigger_match_user(trigger, username, condition, matches,
|
|
MAX_MATCHES)) {
|
|
gm_world_apply_trigger(world, trigger, username, matches);
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_fields(GmMcpVmooUserlist *package, MOOVar *list) {
|
|
MOOVar *field;
|
|
|
|
for (field = list->list; field; field = field->next) {
|
|
if (field->type == STRING) {
|
|
package->priv->fields = g_list_append(package->priv->fields,
|
|
g_strdup(field->s));
|
|
}
|
|
}
|
|
}
|
|
|
|
gchar const *
|
|
gm_mcp_vmoo_userlist_get_icon(GmMcpVmooUserlist *package, UserInfo *ui) {
|
|
gchar *field;
|
|
guint index = ui->icon;
|
|
GmKeyValuePair const *pair;
|
|
|
|
if (index < 1 || index > g_list_length(package->priv->icons)) {
|
|
return NULL;
|
|
} else {
|
|
switch (ui->state) {
|
|
case U_NORMAL:
|
|
field = (gchar *)(g_list_nth_data(package->priv->icons,
|
|
index - 1));
|
|
|
|
pair = icon_mapping;
|
|
|
|
while (!(pair->key == NULL && pair->value == NULL)) {
|
|
if (strcasecmp(pair->key, field) == 0) {
|
|
return pair->value;
|
|
}
|
|
|
|
++pair;
|
|
}
|
|
|
|
break;
|
|
case U_IDLE:
|
|
return "userlist/idle.svg";
|
|
break;
|
|
case U_AWAY:
|
|
return "userlist/away.svg";
|
|
break;
|
|
case U_IDLEAWAY:
|
|
return "userlist/idleaway.svg";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_icons(GmMcpVmooUserlist *package, MOOVar *list) {
|
|
MOOVar *field;
|
|
|
|
for (field = list->list; field; field = field->next) {
|
|
if (field->type == STRING) {
|
|
package->priv->icons = g_list_append(package->priv->icons,
|
|
g_strdup(field->s));
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_menu(GmMcpVmooUserlist *package, MOOVar *list) {
|
|
MOOVar *field;
|
|
GmKeyValuePair *pair;
|
|
|
|
for (field = list->list; field; field = field->next) {
|
|
pair = g_new0(GmKeyValuePair, 1);
|
|
|
|
if (field->type == LIST && field->i == 2) {
|
|
pair->key = g_strdup(field->list->s);
|
|
pair->value = g_strdup(field->list->next->s);
|
|
package->priv->menu = g_list_append(package->priv->menu,
|
|
pair);
|
|
} else if (field->type != LIST) {
|
|
package->priv->menu = g_list_append(package->priv->menu, pair);
|
|
} else {
|
|
g_free(pair);
|
|
}
|
|
}
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_vmoo_userlist_get_string(GmMcpVmooUserlist *package, MOOVar *v,
|
|
MOOType type, gchar *cmp) {
|
|
GList *fields = package->priv->fields;
|
|
|
|
while (fields && strcasecmp(((gchar *) (fields->data)), cmp) != 0) {
|
|
fields = fields->next;
|
|
|
|
if (v) {
|
|
v = v->next;
|
|
}
|
|
}
|
|
|
|
if (v && v->type == type) {
|
|
return g_strdup(v->s);
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
gint
|
|
gm_mcp_vmoo_userlist_get_int(GmMcpVmooUserlist *package, MOOVar *v, MOOType type,
|
|
gchar *cmp) {
|
|
GList *fields = package->priv->fields;
|
|
|
|
while (fields && strcasecmp(((gchar *) (fields->data)), cmp) != 0) {
|
|
fields = fields->next;
|
|
|
|
if (v) {
|
|
v = v->next;
|
|
}
|
|
}
|
|
|
|
if (v && v->type == type) {
|
|
return v->i;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
UserInfo *
|
|
gm_mcp_vmoo_userlist_find_user(GmMcpVmooUserlist *package, gint nr) {
|
|
UserInfo *result;
|
|
GList *users;
|
|
|
|
for (users = package->priv->users; users; users = users->next) {
|
|
result = (UserInfo *) (users->data);
|
|
|
|
if (result->nr == nr) {
|
|
return result;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_vmoo_userlist_menu_item_subst(GmMcpVmooUserlist *package,
|
|
gchar *str, UserInfo *info) {
|
|
GString *result;
|
|
gchar *ptr = str, *subst, *tmp;
|
|
gunichar ch, cnum;
|
|
gint num;
|
|
gboolean substituted;
|
|
|
|
if (str == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
result = g_string_sized_new(strlen(str));
|
|
|
|
while ((ch = g_utf8_get_char(ptr)) != '\0') {
|
|
substituted = FALSE;
|
|
|
|
if (ch == '&') {
|
|
result = g_string_append_c(result, '_');
|
|
substituted = TRUE;
|
|
} else if (ch == '$') {
|
|
subst = g_utf8_next_char(ptr);
|
|
|
|
if (g_utf8_get_char(subst) == '(') {
|
|
subst = g_utf8_next_char(subst);
|
|
num = 0;
|
|
|
|
while (g_unichar_isdigit((cnum = g_utf8_get_char(subst)))) {
|
|
num = (num * 10) + g_unichar_digit_value(cnum);
|
|
subst = g_utf8_next_char(subst);
|
|
}
|
|
|
|
if (g_utf8_get_char(subst) == ')') {
|
|
switch (num) {
|
|
case 1:
|
|
tmp = g_strdup_printf("#%d", info->nr);
|
|
result = g_string_append(result, tmp);
|
|
g_free(tmp);
|
|
break;
|
|
case 2:
|
|
for (tmp = info->name; *tmp != '\0';
|
|
tmp = g_utf8_next_char(tmp)) {
|
|
ch = g_utf8_get_char(tmp);
|
|
|
|
if (ch == '_') {
|
|
result = g_string_append_c(result, '_');
|
|
}
|
|
|
|
result = g_string_append_unichar(result, ch);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ptr = subst;
|
|
substituted = TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!substituted) {
|
|
result = g_string_append_unichar(result, ch);
|
|
}
|
|
|
|
ptr = g_utf8_next_char(ptr);
|
|
}
|
|
|
|
ptr = result->str;
|
|
g_string_free(result, FALSE);
|
|
|
|
return ptr;
|
|
}
|
|
|
|
GmKeyValuePair *
|
|
gm_mcp_vmoo_userlist_get_menu_item(GmMcpVmooUserlist *package,
|
|
GmKeyValuePair *menuitem, UserInfo *info) {
|
|
GmKeyValuePair *result = g_new0(GmKeyValuePair, 1);
|
|
|
|
if (!menuitem) {
|
|
return result;
|
|
}
|
|
|
|
result->key = gm_mcp_vmoo_userlist_menu_item_subst(package,
|
|
menuitem->key, info);
|
|
result->value = gm_mcp_vmoo_userlist_menu_item_subst(package,
|
|
menuitem->value, info);
|
|
|
|
return result;
|
|
}
|
|
|
|
GList *
|
|
gm_mcp_vmoo_userlist_get_menu(GmIUserlist *userlist, gint id) {
|
|
GmMcpVmooUserlist *package = (GmMcpVmooUserlist *)(userlist);
|
|
UserInfo *info = gm_mcp_vmoo_userlist_find_user(package, id);
|
|
GList *item, *menu = NULL;
|
|
GmKeyValuePair *pair;
|
|
|
|
if (!info) {
|
|
return NULL;
|
|
}
|
|
|
|
for (item = package->priv->menu; item; item = item->next) {
|
|
pair = (GmKeyValuePair *)(item->data);
|
|
menu = g_list_append(menu, gm_mcp_vmoo_userlist_get_menu_item(package,
|
|
pair, info));
|
|
}
|
|
|
|
return menu;
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_remove_user(GmMcpVmooUserlist *package, gint nr) {
|
|
GList *elem;
|
|
UserInfo *ui;
|
|
|
|
for (elem = package->priv->users; elem; elem = elem->next) {
|
|
ui = (UserInfo *) (elem->data);
|
|
|
|
if (ui->nr == nr) {
|
|
gm_mcp_vmoo_userlist_process_triggers(package, ui->name,
|
|
TCT_USER_OFFLINE);
|
|
|
|
package->priv->users = g_list_remove(package->priv->users, ui);
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_signal_emit(package, gm_mcp_vmoo_userlist_signals[PLAYER_REMOVED], 0,
|
|
nr);
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_vmoo_userlist_sort_string(GmMcpVmooUserlist *package, UserInfo *ui) {
|
|
guint sortid = 0;
|
|
|
|
switch (ui->state) {
|
|
case U_NORMAL:
|
|
sortid = g_list_length(package->priv->icons) - ui->icon;
|
|
break;
|
|
case U_AWAY:
|
|
sortid = g_list_length(package->priv->icons) + 1;
|
|
break;
|
|
case U_IDLE:
|
|
sortid = g_list_length(package->priv->icons) + 2;
|
|
break;
|
|
case U_IDLEAWAY:
|
|
sortid = g_list_length(package->priv->icons) + 3;
|
|
break;
|
|
}
|
|
|
|
return g_strdup_printf("%.2d%s", sortid, ui->name);
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_user_update(GmMcpVmooUserlist *package, MOOVar *v) {
|
|
gint nr = gm_mcp_vmoo_userlist_get_int(package, v, OBJECT, "object");
|
|
gchar *name = gm_mcp_vmoo_userlist_get_string(package, v, STRING, "name");
|
|
gint icon = gm_mcp_vmoo_userlist_get_int(package, v, INT, "icon");
|
|
gchar *sort;
|
|
|
|
UserInfo *ui;
|
|
|
|
if ((ui = gm_mcp_vmoo_userlist_find_user(package, nr)) == NULL) {
|
|
// Add the user
|
|
ui = g_new(UserInfo, 1);
|
|
ui->name = name;
|
|
ui->state = U_NORMAL;
|
|
ui->icon = icon;
|
|
ui->nr = nr;
|
|
|
|
//
|
|
package->priv->users = g_list_append(package->priv->users, ui);
|
|
sort = gm_mcp_vmoo_userlist_sort_string(package, ui);
|
|
g_signal_emit(package, gm_mcp_vmoo_userlist_signals[PLAYER_ADDED], 0,
|
|
nr, name, gm_mcp_vmoo_userlist_get_icon(package, ui), sort);
|
|
g_free(sort);
|
|
|
|
gm_mcp_vmoo_userlist_process_triggers(package, ui->name,
|
|
TCT_USER_ONLINE);
|
|
} else {
|
|
if (ui->name || strcmp(ui->name, name) != 0) {
|
|
g_free(ui->name);
|
|
ui->name = name;
|
|
|
|
sort = gm_mcp_vmoo_userlist_sort_string(package, ui);
|
|
g_signal_emit(package, gm_mcp_vmoo_userlist_signals[NAME_CHANGED],
|
|
0, nr, name, sort);
|
|
g_free(sort);
|
|
} else {
|
|
g_free(name);
|
|
}
|
|
if (ui->icon != (guint)icon) {
|
|
ui->icon = (guint)icon;
|
|
|
|
sort = gm_mcp_vmoo_userlist_sort_string(package, ui);
|
|
g_signal_emit(package, gm_mcp_vmoo_userlist_signals[RANK_CHANGED],
|
|
0, nr, gm_mcp_vmoo_userlist_get_icon(package, ui), sort);
|
|
g_free(sort);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_set(GmMcpVmooUserlist *package, MOOVar *v) {
|
|
MOOVar *ui;
|
|
|
|
if (v->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
package->priv->initializing = TRUE;
|
|
gm_mcp_vmoo_userlist_remove_users(package);
|
|
|
|
for (ui = v->list; ui; ui = ui->next) {
|
|
if (ui->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
gm_mcp_vmoo_userlist_handle_user_update(package, ui->list);
|
|
}
|
|
|
|
package->priv->initializing = FALSE;
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_add(GmMcpVmooUserlist *package, MOOVar *v) {
|
|
if (v->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
gm_mcp_vmoo_userlist_handle_user_update(package, v->list);
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_remove(GmMcpVmooUserlist *package, MOOVar *v) {
|
|
MOOVar *nr;
|
|
|
|
if (v->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
for (nr = v->list; nr; nr = nr->next) {
|
|
if (nr->type == OBJECT) {
|
|
gm_mcp_vmoo_userlist_remove_user(package, nr->i);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_update(GmMcpVmooUserlist *package, MOOVar *v) {
|
|
if (v->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
gm_mcp_vmoo_userlist_handle_user_update(package, v->list);
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_state(GmMcpVmooUserlist *package, MOOVar *v,
|
|
UserState state, gboolean onOff) {
|
|
MOOVar *nr;
|
|
UserInfo *u;
|
|
gchar *sort;
|
|
GmTriggerConditionType condition = 0;
|
|
|
|
if (v->type != LIST) {
|
|
return;
|
|
}
|
|
|
|
for (nr = v->list; nr; nr = nr->next) {
|
|
if (nr->type == OBJECT) {
|
|
if ((u = gm_mcp_vmoo_userlist_find_user(package, nr->i))) {
|
|
switch (state) {
|
|
case U_IDLE:
|
|
if (u->state == U_IDLEAWAY && !onOff) {
|
|
u->state = U_AWAY;
|
|
} else if (u->state == U_AWAY && onOff) {
|
|
u->state = U_IDLEAWAY;
|
|
} else if (onOff) {
|
|
u->state = U_IDLE;
|
|
} else if (u->state == U_IDLE) {
|
|
u->state = U_NORMAL;
|
|
}
|
|
|
|
if (onOff) {
|
|
condition = TCT_USER_IDLE;
|
|
} else {
|
|
condition = TCT_USER_IDLE_OFF;
|
|
}
|
|
break;
|
|
case U_AWAY:
|
|
if (u->state == U_IDLEAWAY && !onOff) {
|
|
u->state = U_IDLE;
|
|
} else if (u->state == U_IDLE && onOff) {
|
|
u->state = U_IDLEAWAY;
|
|
} else if (onOff) {
|
|
u->state = U_AWAY;
|
|
} else if (u->state == U_AWAY) {
|
|
u->state = U_NORMAL;
|
|
}
|
|
|
|
if (onOff) {
|
|
condition = TCT_USER_AWAY;
|
|
} else {
|
|
condition = TCT_USER_AWAY_OFF;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
sort = gm_mcp_vmoo_userlist_sort_string(package, u);
|
|
|
|
g_signal_emit(package,
|
|
gm_mcp_vmoo_userlist_signals[STATE_CHANGED], 0,
|
|
nr->i, gm_mcp_vmoo_userlist_get_icon(package, u), sort);
|
|
|
|
if (condition != 0) {
|
|
gm_mcp_vmoo_userlist_process_triggers(package, u->name,
|
|
condition);
|
|
}
|
|
|
|
g_free(sort);
|
|
} else {
|
|
gm_debug_msg(DEBUG_MCP, "User %d does not exist!", nr->i);
|
|
}
|
|
} else {
|
|
gm_debug_msg(DEBUG_MCP, "Nr is not an object: %d", nr->type);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_handle_simple(GmMcpPackage *package, gchar *suffix,
|
|
GList *fields) {
|
|
MOOVar *v = NULL;
|
|
GmMcpVmooUserlist *userlist = GM_MCP_VMOO_USERLIST(package);
|
|
gchar const *value;
|
|
|
|
if (suffix) {
|
|
if (strcmp(suffix, "you") == 0) {
|
|
v = MOOVar_parse(gm_mcp_find_value(fields, "nr"));
|
|
|
|
if (v->type == OBJECT) {
|
|
userlist->priv->you = v->i;
|
|
} else {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleSimple: "
|
|
"you is not an object!");
|
|
}
|
|
} else if (strcmp(suffix, "menu") == 0) {
|
|
value = gm_mcp_find_value(fields, "menu");
|
|
v = MOOVar_parse(value);
|
|
|
|
if (!v || v->type != LIST) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleMulti: "
|
|
"invalid value: %s", value);
|
|
} else {
|
|
gm_mcp_vmoo_userlist_free_menu(userlist);
|
|
gm_mcp_vmoo_userlist_handle_menu(userlist, v);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (v) {
|
|
MOOVar_free(v);
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
gm_mcp_vmoo_userlist_handle_multi(GmMcpPackage *package,
|
|
gchar const *data_tag, gchar const *key, gchar const *value,
|
|
GList *all_values) {
|
|
MOOVar *v = NULL;
|
|
GmMcpVmooUserlist *userlist = GM_MCP_VMOO_USERLIST(package);
|
|
|
|
if (key) {
|
|
if (strcmp(key, "fields") == 0) {
|
|
v = MOOVar_parse(value);
|
|
|
|
if (!v || v->type != LIST) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleMulti: "
|
|
"invalid value: %s", value);
|
|
} else {
|
|
gm_mcp_vmoo_userlist_handle_fields(userlist, v);
|
|
}
|
|
} else if (strcmp(key, "icons") == 0) {
|
|
v = MOOVar_parse(value);
|
|
|
|
if (!v || v->type != LIST) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleMulti: "
|
|
"invalid value: %s", value);
|
|
} else {
|
|
gm_mcp_vmoo_userlist_handle_icons(userlist, v);
|
|
}
|
|
} else if (strcmp(key, "d") == 0) {
|
|
v = MOOVar_parse(value + 1);
|
|
|
|
if (!v) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleMulti: "
|
|
"invalid value: %s", value + 1);
|
|
} else {
|
|
switch (*value) {
|
|
case '=':
|
|
gm_mcp_vmoo_userlist_handle_set(userlist, v);
|
|
break;
|
|
case '+':
|
|
gm_mcp_vmoo_userlist_handle_add(userlist, v);
|
|
break;
|
|
case '-':
|
|
gm_mcp_vmoo_userlist_handle_remove(userlist, v);
|
|
break;
|
|
case '*':
|
|
gm_mcp_vmoo_userlist_handle_update(userlist, v);
|
|
break;
|
|
case '<':
|
|
gm_mcp_vmoo_userlist_handle_state(userlist, v, U_IDLE,
|
|
TRUE);
|
|
break;
|
|
case '>':
|
|
gm_mcp_vmoo_userlist_handle_state(userlist, v, U_IDLE,
|
|
FALSE);
|
|
break;
|
|
case '[':
|
|
gm_mcp_vmoo_userlist_handle_state(userlist, v, U_AWAY,
|
|
TRUE);
|
|
break;
|
|
case ']':
|
|
gm_mcp_vmoo_userlist_handle_state(userlist, v, U_AWAY,
|
|
FALSE);
|
|
break;
|
|
case '(':
|
|
gm_mcp_vmoo_userlist_handle_remove(userlist, v);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (v) {
|
|
MOOVar_free(v);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
gm_mcp_vmoo_userlist_create_view(GmMcpPackage *package, GObject *parent) {
|
|
gm_mcp_userlist_view_new(package, parent);
|
|
}
|