991 lines
27 KiB
C
991 lines
27 KiB
C
#include <glib.h>
|
|
#include <string.h>
|
|
#include <glob.h>
|
|
#include <unistd.h>
|
|
#include <errno.h>
|
|
|
|
#include "gm-mcp-icecrew-userlist.h"
|
|
#include "gm-mcp-userlist-view.h"
|
|
#include "gm-mcp-icecrew-playerdb.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"
|
|
|
|
#define GM_MCP_ICECREW_USERLIST_GET_PRIVATE(object)( \
|
|
G_TYPE_INSTANCE_GET_PRIVATE((object), \
|
|
GM_TYPE_MCP_ICECREW_USERLIST, GmMcpIcecrewUserlistPrivate))
|
|
|
|
#define USERLIST_ICON_SIZE 22
|
|
|
|
static GmKeyValuePair default_states[] = {
|
|
{"away+idle", "ice-userlist/away+idle.svg"},
|
|
{"busy+idle", "ice-userlist/busy+idle.svg"},
|
|
{"away", "ice-userlist/away.svg"},
|
|
{"busy", "ice-userlist/busy.svg"},
|
|
{"avail+idle", "ice-userlist/avail+idle.svg"},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
static GmKeyValuePair default_ranks[] = {
|
|
{"inhabitant", "ice-userlist/inhabitant.svg"},
|
|
{"programmer", "ice-userlist/programmer.svg"},
|
|
{"wizard", "ice-userlist/wizard.svg"},
|
|
{NULL, NULL}
|
|
};
|
|
|
|
struct _GmMcpIcecrewUserlistPrivate {
|
|
GList *state_icons;
|
|
GList *rank_icons;
|
|
GList *state_alternatives;
|
|
GList *rank_alternatives;
|
|
|
|
GList *key_datatags;
|
|
GmFetchHandle *rank_fetch;
|
|
GmFetchHandle *state_fetch;
|
|
|
|
gchar *rank_dir;
|
|
gchar *state_dir;
|
|
};
|
|
|
|
static gchar *gm_mcp_icecrew_userlist_depends[] = {
|
|
"dns-nl-icecrew-playerdb",
|
|
NULL
|
|
};
|
|
static gchar *gm_mcp_icecrew_userlist_overrides[] = {
|
|
"dns-com-vmoo-userlist",
|
|
NULL
|
|
};
|
|
|
|
/* Signals */
|
|
|
|
enum {
|
|
PLAYER_ADDED,
|
|
PLAYER_REMOVED,
|
|
NAME_CHANGED,
|
|
STATE_CHANGED,
|
|
RANK_CHANGED,
|
|
NUM_SIGNALS
|
|
};
|
|
|
|
static guint gm_mcp_icecrew_userlist_signals[NUM_SIGNALS] = {0};
|
|
|
|
G_DEFINE_TYPE(GmMcpIcecrewUserlist, gm_mcp_icecrew_userlist, GM_TYPE_MCP_PACKAGE)
|
|
|
|
void on_gm_mcp_icecrew_userlist_add(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, GmMcpIcecrewUserlist *userlist);
|
|
void on_gm_mcp_icecrew_userlist_set(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, gchar const *key, gchar const *value,
|
|
gchar const *old, GmMcpIcecrewUserlist *userlist);
|
|
void on_gm_mcp_icecrew_userlist_delete(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, GmMcpIcecrewUserlist *userlist);
|
|
|
|
void on_gm_mcp_icecrew_userlist_fetch_progress(GmFetchHandle *g,
|
|
GmMcpIcecrewUserlist *package);
|
|
|
|
gboolean gm_mcp_icecrew_userlist_handle_multi(GmMcpPackage *package,
|
|
gchar const *data_tag, gchar const *key, gchar const *value,
|
|
GList *all_values);
|
|
|
|
void gm_mcp_icecrew_userlist_set_session(GmMcpPackage *package,
|
|
GObject *session);
|
|
void gm_mcp_icecrew_userlist_create_view(GmMcpPackage *package,
|
|
GObject *parent);
|
|
|
|
void gm_mcp_icecrew_userlist_fetch_progress(GmFetchHandle *g,
|
|
GmMcpIcecrewUserlist *package);
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_pair_free(GmKeyValuePair *pair) {
|
|
g_free(pair->key);
|
|
g_free(pair->value);
|
|
g_free(pair);
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_free_list(GList *rs) {
|
|
GList *item;
|
|
|
|
for (item = rs; item; item = item->next) {
|
|
gm_mcp_icecrew_userlist_pair_free((GmKeyValuePair *)(item->data));
|
|
}
|
|
|
|
g_list_free(rs);
|
|
}
|
|
|
|
static void
|
|
gm_mcp_icecrew_userlist_finalize(GObject *object) {
|
|
GmMcpIcecrewUserlist *obj = GM_MCP_ICECREW_USERLIST(object);
|
|
GmMcpPackage *playerdb = gm_mcp_session_find_package(
|
|
GM_MCP_PACKAGE_SESSION(obj), "dns-nl-icecrew-playerdb");
|
|
|
|
if (playerdb) {
|
|
g_signal_handlers_disconnect_by_func(playerdb,
|
|
on_gm_mcp_icecrew_userlist_add, obj);
|
|
g_signal_handlers_disconnect_by_func(playerdb,
|
|
on_gm_mcp_icecrew_userlist_set, obj);
|
|
g_signal_handlers_disconnect_by_func(playerdb,
|
|
on_gm_mcp_icecrew_userlist_delete, obj);
|
|
}
|
|
|
|
gm_mcp_icecrew_userlist_free_list(obj->priv->state_icons);
|
|
gm_mcp_icecrew_userlist_free_list(obj->priv->rank_icons);
|
|
gm_mcp_icecrew_userlist_free_list(obj->priv->key_datatags);
|
|
|
|
g_free(obj->priv->rank_dir);
|
|
g_free(obj->priv->state_dir);
|
|
|
|
if (obj->priv->rank_fetch) {
|
|
obj->priv->rank_fetch->aborted = TRUE;
|
|
}
|
|
|
|
if (obj->priv->state_fetch) {
|
|
obj->priv->state_fetch->aborted = TRUE;
|
|
}
|
|
|
|
G_OBJECT_CLASS(gm_mcp_icecrew_userlist_parent_class)->finalize(object);
|
|
}
|
|
|
|
static void
|
|
gm_mcp_icecrew_userlist_class_init(GmMcpIcecrewUserlistClass *klass) {
|
|
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
|
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
|
|
|
|
object_class->finalize = gm_mcp_icecrew_userlist_finalize;
|
|
|
|
gm_mcp_icecrew_userlist_signals[PLAYER_ADDED] =
|
|
g_signal_new("player_added",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpIcecrewUserlistClass, 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_icecrew_userlist_signals[PLAYER_REMOVED] =
|
|
g_signal_new("player_removed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpIcecrewUserlistClass, player_removed),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__INT,
|
|
G_TYPE_NONE,
|
|
1,
|
|
G_TYPE_INT);
|
|
gm_mcp_icecrew_userlist_signals[NAME_CHANGED] =
|
|
g_signal_new("name_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpIcecrewUserlistClass, 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_icecrew_userlist_signals[STATE_CHANGED] =
|
|
g_signal_new("state_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpIcecrewUserlistClass, 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_icecrew_userlist_signals[RANK_CHANGED] =
|
|
g_signal_new("rank_changed",
|
|
G_OBJECT_CLASS_TYPE(object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET(GmMcpIcecrewUserlistClass, 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-nl-icecrew-userlist";
|
|
pklass->depends = gm_mcp_icecrew_userlist_depends;
|
|
pklass->overrides = gm_mcp_icecrew_userlist_overrides;
|
|
|
|
pklass->set_session = &gm_mcp_icecrew_userlist_set_session;
|
|
pklass->handle_multi = &gm_mcp_icecrew_userlist_handle_multi;
|
|
pklass->create_view = &gm_mcp_icecrew_userlist_create_view;
|
|
|
|
g_type_class_add_private(object_class, sizeof(GmMcpIcecrewUserlistPrivate));
|
|
}
|
|
|
|
GmKeyValuePair *
|
|
gm_mcp_icecrew_userlist_url_map_new(gchar const *name, gchar const *filename) {
|
|
GmKeyValuePair *r = g_new(GmKeyValuePair, 1);
|
|
|
|
r->key = g_strdup(name);
|
|
r->value = g_strdup(filename);
|
|
|
|
return r;
|
|
}
|
|
|
|
GList *
|
|
gm_mcp_icecrew_userlist_find_icon_names(GList *icons, gchar const *path) {
|
|
GList *item, *res = NULL;
|
|
GmKeyValuePair *map;
|
|
|
|
for (item = icons; item; item = item->next) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
|
|
if (strcmp(map->value, path) == 0) {
|
|
res = g_list_append(res, map->key);
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
guint
|
|
gm_mcp_icecrew_userlist_find_path(GList *icons, gchar const *name,
|
|
gchar **path) {
|
|
GList *item;
|
|
GmKeyValuePair *map;
|
|
guint position = 0;
|
|
|
|
for (item = icons; item; item = item->next) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
|
|
if (strcmp(map->key, name) == 0) {
|
|
if (path != NULL) {
|
|
*path = map->value;
|
|
}
|
|
return position;
|
|
}
|
|
|
|
++position;
|
|
}
|
|
|
|
if (path != NULL) {
|
|
*path = NULL;
|
|
}
|
|
|
|
return position + 1;
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_remove_datatag(GmMcpIcecrewUserlist *package,
|
|
gchar const *datatag) {
|
|
GList *item;
|
|
GmKeyValuePair *map;
|
|
|
|
for (item = package->priv->key_datatags; item; item = item->next) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
|
|
if (strcmp(map->value, datatag) == 0) {
|
|
gm_mcp_icecrew_userlist_pair_free(map);
|
|
|
|
package->priv->key_datatags = g_list_remove_link(
|
|
package->priv->key_datatags, item);
|
|
g_list_free_1(item);
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
gchar const *
|
|
gm_mcp_icecrew_userlist_find_key(GmMcpIcecrewUserlist *package,
|
|
gchar const *datatag) {
|
|
GList *item;
|
|
GmKeyValuePair *map;
|
|
|
|
for (item = package->priv->key_datatags; item; item = item->next) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
|
|
if (strcmp(map->value, datatag) == 0) {
|
|
return map->key;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
gchar const *
|
|
gm_mcp_icecrew_userlist_find_name(gchar const *name,
|
|
GmKeyValuePair def[]) {
|
|
GmKeyValuePair *pair = def;
|
|
|
|
while (!(pair->key == NULL && pair->value == NULL)) {
|
|
if (strcmp(pair->key, name) == 0) {
|
|
return pair->value;
|
|
}
|
|
|
|
++pair;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_init_states(GmMcpIcecrewUserlist *package) {
|
|
GmKeyValuePair *pair = default_states;
|
|
|
|
package->priv->state_icons = NULL;
|
|
|
|
while (!(pair->key == NULL && pair->value == NULL)) {
|
|
package->priv->state_icons = g_list_append(package->priv->state_icons,
|
|
gm_mcp_icecrew_userlist_url_map_new(pair->key, pair->value));
|
|
++pair;
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_init_ranks(GmMcpIcecrewUserlist *package) {
|
|
GmKeyValuePair *pair = default_ranks;
|
|
|
|
package->priv->rank_icons = NULL;
|
|
|
|
while (!(pair->key == NULL && pair->value == NULL)) {
|
|
package->priv->rank_icons = g_list_append(package->priv->rank_icons,
|
|
gm_mcp_icecrew_userlist_url_map_new(pair->key, pair->value));
|
|
++pair;
|
|
}
|
|
}
|
|
|
|
static void
|
|
gm_mcp_icecrew_userlist_init(GmMcpIcecrewUserlist *obj) {
|
|
obj->priv = GM_MCP_ICECREW_USERLIST_GET_PRIVATE(obj);
|
|
|
|
obj->priv->rank_alternatives = NULL;
|
|
obj->priv->state_alternatives = NULL;
|
|
obj->priv->key_datatags = NULL;
|
|
obj->priv->rank_dir = NULL;
|
|
obj->priv->state_dir = NULL;
|
|
obj->priv->rank_fetch = NULL;
|
|
obj->priv->state_fetch = NULL;
|
|
|
|
gm_mcp_icecrew_userlist_init_states(obj);
|
|
gm_mcp_icecrew_userlist_init_ranks(obj);
|
|
}
|
|
|
|
GmMcpIcecrewUserlist *
|
|
gm_mcp_icecrew_userlist_new() {
|
|
GmMcpIcecrewUserlist *obj = GM_MCP_ICECREW_USERLIST(g_object_new(
|
|
GM_TYPE_MCP_ICECREW_USERLIST, NULL));
|
|
|
|
return obj;
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_icecrew_userlist_remote_to_local_path(gchar const *url,
|
|
gchar const *dirname) {
|
|
gchar *base = g_path_get_basename(url);
|
|
gchar *result;
|
|
|
|
result = g_strconcat(dirname, G_DIR_SEPARATOR_S, base, NULL);
|
|
g_free(base);
|
|
|
|
return result;
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_remove_alternatives(GmMcpIcecrewUserlist *package,
|
|
gchar *path, gint n, gboolean rank) {
|
|
GList *item, **alter;
|
|
gint i;
|
|
GmKeyValuePair *map;
|
|
gchar *name, *pathd, *dir;
|
|
|
|
alter = rank ? &(package->priv->rank_alternatives) :
|
|
&(package->priv->state_alternatives);
|
|
dir = rank ? package->priv->rank_dir : package->priv->state_dir;
|
|
|
|
for (item = *alter; item; item = item->next) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
pathd = gm_mcp_icecrew_userlist_remote_to_local_path(map->value, dir);
|
|
|
|
if (strcmp(pathd, path) == 0) {
|
|
name = g_strdup(map->key);
|
|
i = 0;
|
|
|
|
while (item && (n == 0 || i < n)) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
++i;
|
|
|
|
if (strcmp(map->key, name) == 0) {
|
|
item = item->next;
|
|
*alter = g_list_remove(*alter, map);
|
|
gm_mcp_icecrew_userlist_pair_free(map);
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_free(name);
|
|
|
|
break;
|
|
}
|
|
|
|
g_free(path);
|
|
}
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_icecrew_userlist_sort_string(GmMcpIcecrewUserlist *package,
|
|
GmPlayerdbPlayerInfo *ppi) {
|
|
/* Find the appropriate icon */
|
|
gchar const *state = gm_playerdb_player_info_get_prop(ppi, "P_STATE");
|
|
gchar const *rank = gm_playerdb_player_info_get_prop(ppi, "P_RANK");
|
|
gchar const *name = gm_playerdb_player_info_get_prop(ppi, "P_NAME");
|
|
gint sortid;
|
|
|
|
/* Sort on icon, and then on name */
|
|
if (strcmp(state, "avail") == 0) {
|
|
sortid = g_list_length(package->priv->rank_icons) -
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->rank_icons,
|
|
rank, NULL) - 1;
|
|
} else {
|
|
sortid = (g_list_length(package->priv->state_icons) -
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->state_icons,
|
|
state, NULL) - 1) + g_list_length(package->priv->rank_icons);
|
|
}
|
|
|
|
return g_strdup_printf("%.2d%s", sortid, name);
|
|
}
|
|
|
|
gchar *
|
|
gm_mcp_icecrew_userlist_icon_path(GmMcpIcecrewUserlist *package,
|
|
GmPlayerdbPlayerInfo *ppi) {
|
|
gchar const *state;
|
|
gchar *icon_path = NULL;
|
|
|
|
state = gm_playerdb_player_info_get_prop(ppi, "P_STATE");
|
|
|
|
if (state && strcmp(state, "avail") == 0) {
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->rank_icons,
|
|
gm_playerdb_player_info_get_prop(ppi, "P_RANK"), &icon_path);
|
|
} else {
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->state_icons,
|
|
state, &icon_path);
|
|
|
|
}
|
|
|
|
return icon_path;
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_update_rank_icon(GmPlayerdbPlayerInfo *ppi,
|
|
gpointer user_data) {
|
|
GmMcpIcecrewUserlist *package = GM_MCP_ICECREW_USERLIST(user_data);
|
|
gchar const *state;
|
|
gchar *icon_path;
|
|
|
|
state = gm_playerdb_player_info_get_prop(ppi, "P_STATE");
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.UpdateRankIcon: %s", state);
|
|
|
|
if (state && strcmp(state, "avail") == 0) {
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->rank_icons,
|
|
gm_playerdb_player_info_get_prop(ppi, "P_RANK"), &icon_path);
|
|
|
|
g_signal_emit(package, gm_mcp_icecrew_userlist_signals[RANK_CHANGED],
|
|
0, ppi->id, icon_path, NULL);
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_update_state_icon(GmPlayerdbPlayerInfo *ppi,
|
|
gpointer user_data) {
|
|
GmMcpIcecrewUserlist *package = GM_MCP_ICECREW_USERLIST(user_data);
|
|
gchar *icon_path;
|
|
|
|
gm_mcp_icecrew_userlist_find_path(package->priv->state_icons,
|
|
gm_playerdb_player_info_get_prop(ppi, "P_STATE"), &icon_path);
|
|
|
|
g_signal_emit(package, gm_mcp_icecrew_userlist_signals[STATE_CHANGED],
|
|
0, ppi->id, icon_path, NULL);
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_new_rank_state_icon(GmMcpIcecrewUserlist *package,
|
|
gchar *path, gboolean rank) {
|
|
GList *names;
|
|
GList *tmp;
|
|
GmMcpPackage *playerdb;
|
|
|
|
playerdb = gm_mcp_session_find_package(GM_MCP_PACKAGE_SESSION(package),
|
|
"dns-nl-icecrew-playerdb");
|
|
|
|
g_return_if_fail(playerdb != NULL);
|
|
|
|
if (rank) {
|
|
names = gm_mcp_icecrew_userlist_find_icon_names(
|
|
package->priv->rank_icons, path);
|
|
} else {
|
|
names = gm_mcp_icecrew_userlist_find_icon_names(
|
|
package->priv->state_icons, path);
|
|
}
|
|
|
|
if (names == NULL) {
|
|
return;
|
|
}
|
|
|
|
for (tmp = names; tmp; tmp = tmp->next) {
|
|
if (rank) {
|
|
gm_mcp_icecrew_playerdb_find_players_with(
|
|
GM_MCP_ICECREW_PLAYERDB(playerdb), "P_RANK",
|
|
(gchar *)(tmp->data),
|
|
gm_mcp_icecrew_userlist_update_rank_icon, package);
|
|
} else {
|
|
gm_mcp_icecrew_playerdb_find_players_with(
|
|
GM_MCP_ICECREW_PLAYERDB(playerdb), "P_STATE",
|
|
(gchar *)(tmp->data),
|
|
gm_mcp_icecrew_userlist_update_state_icon, package);
|
|
}
|
|
}
|
|
|
|
g_list_free(names);
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_remove_not_used_icons(GList *icons, gchar *dir) {
|
|
glob_t gl;
|
|
guint i;
|
|
GList *names;
|
|
gchar *g = g_strconcat(dir, G_DIR_SEPARATOR_S, "*", NULL);
|
|
|
|
glob(g, 0, NULL, &gl);
|
|
|
|
for (i = 0; i < gl.gl_pathc; ++i) {
|
|
names = gm_mcp_icecrew_userlist_find_icon_names(icons, gl.gl_pathv[i]);
|
|
|
|
if (!names) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.RemoveNotUsedIcons: "
|
|
"removing %s", gl.gl_pathv[i]);
|
|
|
|
if (unlink(gl.gl_pathv[i]) == -1) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.RemoveNotUsedIcons: "
|
|
"error %s", strerror(errno));
|
|
}
|
|
} else {
|
|
g_list_free(names);
|
|
}
|
|
}
|
|
|
|
g_free(g);
|
|
globfree(&gl);
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_fetch_next_alternatives(GmMcpIcecrewUserlist *package,
|
|
gboolean rank) {
|
|
GList *source_uri = NULL, *dest_uri = NULL;
|
|
gchar *prev_name = NULL, *path;
|
|
GList *item, **alter, *iter;
|
|
GmKeyValuePair *map, *itermap;
|
|
GnomeVFSResult result;
|
|
GnomeVFSFileInfo *finfo;
|
|
|
|
/* Select unique name alternatives */
|
|
alter = rank ? &(package->priv->rank_alternatives) :
|
|
&(package->priv->state_alternatives);
|
|
item = *alter;
|
|
|
|
while (item) {
|
|
map = (GmKeyValuePair *)(item->data);
|
|
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchNextAlternatives: "
|
|
"checking: %s", map->value);
|
|
|
|
/* Skip alternatives with names we've already stored to be fetched */
|
|
if (prev_name == NULL || strcmp(map->key, prev_name) != 0) {
|
|
finfo = gnome_vfs_file_info_new();
|
|
result = gnome_vfs_get_file_info(map->value, finfo,
|
|
GNOME_VFS_FILE_INFO_DEFAULT);
|
|
gnome_vfs_file_info_unref(finfo);
|
|
|
|
if (result != GNOME_VFS_OK) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist."
|
|
"FetchNextAlternatives: removing %s because it's "
|
|
"invalid: %s", map->value,
|
|
gnome_vfs_result_to_string(result));
|
|
item = item->next;
|
|
|
|
*alter = g_list_remove(*alter, map);
|
|
gm_mcp_icecrew_userlist_pair_free(map);
|
|
} else {
|
|
prev_name = map->key;
|
|
|
|
path = gm_mcp_icecrew_userlist_remote_to_local_path(map->value,
|
|
rank ? package->priv->rank_dir :
|
|
package->priv->state_dir);
|
|
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist."
|
|
"FetchNextAlternatives: adding to be fetched: %s => %s",
|
|
map->key, map->value);
|
|
|
|
source_uri = g_list_append(source_uri, map->value);
|
|
dest_uri = g_list_append(dest_uri, path);
|
|
|
|
unlink(path);
|
|
|
|
for (iter = rank ? package->priv->rank_icons :
|
|
package->priv->state_icons; iter; iter = iter->next) {
|
|
itermap = (GmKeyValuePair *)(iter->data);
|
|
|
|
if (strcmp(itermap->key, map->key) == 0) {
|
|
g_free(itermap->value);
|
|
itermap->value = g_strdup(path);
|
|
break;
|
|
}
|
|
}
|
|
|
|
item = item->next;
|
|
}
|
|
} else {
|
|
item = item->next;
|
|
}
|
|
}
|
|
|
|
if (source_uri != NULL) {
|
|
if (rank) {
|
|
package->priv->rank_fetch = gm_fetch(source_uri, dest_uri,
|
|
(GFunc)gm_mcp_icecrew_userlist_fetch_progress, package);
|
|
} else {
|
|
package->priv->state_fetch = gm_fetch(source_uri, dest_uri,
|
|
(GFunc)gm_mcp_icecrew_userlist_fetch_progress, package);
|
|
}
|
|
|
|
gm_g_list_free_simple(dest_uri);
|
|
} else {
|
|
if (rank) {
|
|
gm_mcp_icecrew_userlist_remove_not_used_icons(
|
|
package->priv->rank_icons, package->priv->rank_dir);
|
|
} else {
|
|
gm_mcp_icecrew_userlist_remove_not_used_icons(
|
|
package->priv->state_icons, package->priv->state_dir);
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_fetch_progress(GmFetchHandle *g,
|
|
GmMcpIcecrewUserlist *package) {
|
|
gchar *path;
|
|
gboolean rank = (package->priv->rank_fetch == g);
|
|
GdkPixbuf *pixtest;
|
|
GError *err = NULL;
|
|
|
|
if (g->aborted) {
|
|
if (rank) {
|
|
package->priv->rank_fetch = NULL;
|
|
gm_mcp_icecrew_userlist_free_list(
|
|
package->priv->rank_alternatives);
|
|
package->priv->rank_alternatives = NULL;
|
|
} else {
|
|
package->priv->state_fetch = NULL;
|
|
gm_mcp_icecrew_userlist_free_list(
|
|
package->priv->state_alternatives);
|
|
package->priv->state_alternatives = NULL;
|
|
}
|
|
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
|
|
"fetch aborted!");
|
|
return;
|
|
}
|
|
|
|
if (g->done) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
|
|
"fetch done!");
|
|
|
|
if (rank) {
|
|
package->priv->rank_fetch = NULL;
|
|
gm_mcp_icecrew_userlist_fetch_next_alternatives(package, TRUE);
|
|
} else {
|
|
package->priv->state_fetch = NULL;
|
|
gm_mcp_icecrew_userlist_fetch_next_alternatives(package, FALSE);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (g->status == GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR) {
|
|
/* Skip to the next alternative (in the next run, see on done */
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: error");
|
|
path = gnome_vfs_get_local_path_from_uri(g->cur_file_name);
|
|
gm_mcp_icecrew_userlist_remove_alternatives(package, path, 1, rank);
|
|
g_free(path);
|
|
}
|
|
|
|
if (g->cur_phase == GNOME_VFS_XFER_PHASE_FILECOMPLETED) {
|
|
path = gnome_vfs_get_local_path_from_uri(g->cur_file_name);
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
|
|
"%s fetched!", path);
|
|
pixtest = gdk_pixbuf_new_from_file(path, &err);
|
|
|
|
if (pixtest) {
|
|
/* Remove alternatives which don't need to be fetched anymore */
|
|
g_object_unref(pixtest);
|
|
gm_mcp_icecrew_userlist_remove_alternatives(package, path, 0, rank);
|
|
|
|
if (rank) {
|
|
gm_mcp_icecrew_userlist_new_rank_state_icon(package, path,
|
|
TRUE);
|
|
} else {
|
|
gm_mcp_icecrew_userlist_new_rank_state_icon(package, path,
|
|
FALSE);
|
|
}
|
|
} else {
|
|
/* This failed! */
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
|
|
"error, couldn't load file: %s", err->message);
|
|
g_error_free(err);
|
|
gm_mcp_icecrew_userlist_remove_alternatives(package, path, 1, rank);
|
|
}
|
|
|
|
g_free(path);
|
|
}
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_handle_ranks_states(GmMcpIcecrewUserlist *package,
|
|
GList *values, gboolean rank) {
|
|
GList *tmp, *data, *new_list = NULL;
|
|
gchar *name, **alternatives, *path, **ptr;
|
|
gchar const *cpath;
|
|
|
|
for (tmp = values; tmp; tmp = tmp->next) {
|
|
data = (GList *)(tmp->data);
|
|
|
|
if (data == NULL ) {
|
|
continue;
|
|
}
|
|
|
|
name = (gchar *)(data->data);
|
|
gm_mcp_icecrew_userlist_find_path(new_list, name, &path);
|
|
|
|
if (path) {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.HandleRanksStates: "
|
|
"duplicate %s, ignored!", name);
|
|
continue;
|
|
}
|
|
|
|
if (data->next == NULL) {
|
|
if (rank) {
|
|
cpath = gm_mcp_icecrew_userlist_find_name(name, default_ranks);
|
|
} else {
|
|
cpath = gm_mcp_icecrew_userlist_find_name(name, default_states);
|
|
}
|
|
|
|
if (cpath) {
|
|
new_list = g_list_append(new_list,
|
|
gm_mcp_icecrew_userlist_url_map_new(name, cpath));
|
|
} else {
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist."
|
|
"HandleRanksStates: couldn't find %s, ignored!", name);
|
|
}
|
|
} else {
|
|
alternatives = g_strsplit(g_list_nth_data(data, 1), ";", 0);
|
|
ptr = alternatives;
|
|
|
|
while (*ptr) {
|
|
/* Initialize to first alternative */
|
|
if (ptr == alternatives) {
|
|
path = gm_mcp_icecrew_userlist_remote_to_local_path(
|
|
*ptr, rank ? package->priv->rank_dir :
|
|
package->priv->state_dir);
|
|
new_list = g_list_append(new_list,
|
|
gm_mcp_icecrew_userlist_url_map_new(name, path));
|
|
g_free(path);
|
|
}
|
|
|
|
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.HandleRanksStates: "
|
|
"adding alternative: %s => %s", name, *ptr);
|
|
|
|
if (rank) {
|
|
package->priv->rank_alternatives = g_list_append(
|
|
package->priv->rank_alternatives,
|
|
gm_mcp_icecrew_userlist_url_map_new(name,
|
|
*ptr));
|
|
} else {
|
|
package->priv->state_alternatives = g_list_append(
|
|
package->priv->state_alternatives,
|
|
gm_mcp_icecrew_userlist_url_map_new(name,
|
|
*ptr));
|
|
}
|
|
|
|
++ptr;
|
|
}
|
|
|
|
g_strfreev(alternatives);
|
|
}
|
|
}
|
|
|
|
if (rank) {
|
|
gm_mcp_icecrew_userlist_free_list(package->priv->rank_icons);
|
|
package->priv->rank_icons = new_list;
|
|
} else {
|
|
gm_mcp_icecrew_userlist_free_list(package->priv->state_icons);
|
|
package->priv->state_icons = new_list;
|
|
}
|
|
|
|
/* Abort a previous fetch if needed */
|
|
if (rank && package->priv->rank_fetch) {
|
|
package->priv->rank_fetch->aborted = TRUE;
|
|
} else if (!rank && package->priv->state_fetch) {
|
|
package->priv->state_fetch->aborted = TRUE;
|
|
}
|
|
|
|
/* Wait for vfs async to be aborted */
|
|
while ((rank && package->priv->rank_fetch != NULL) ||
|
|
(!rank && package->priv->state_fetch != NULL)) {
|
|
gm_do_events();
|
|
}
|
|
|
|
if (rank && package->priv->rank_alternatives) {
|
|
gm_mcp_icecrew_userlist_fetch_next_alternatives(package, rank);
|
|
} else if (!rank && package->priv->state_alternatives) {
|
|
gm_mcp_icecrew_userlist_fetch_next_alternatives(package, rank);
|
|
}
|
|
}
|
|
|
|
gboolean
|
|
gm_mcp_icecrew_userlist_handle_multi(GmMcpPackage *package,
|
|
gchar const *data_tag, gchar const *key, gchar const *value,
|
|
GList *all_values) {
|
|
GmMcpIcecrewUserlist *userlist = GM_MCP_ICECREW_USERLIST(package);
|
|
GList *tmp, *l, *vals = NULL;
|
|
GmKeyValuePair *m;
|
|
|
|
if (key) {
|
|
if (!gm_mcp_icecrew_userlist_find_key(userlist, data_tag)) {
|
|
m = g_new(GmKeyValuePair, 1);
|
|
m->key = g_strdup(key);
|
|
m->value = g_strdup(data_tag);
|
|
|
|
userlist->priv->key_datatags = g_list_append(
|
|
userlist->priv->key_datatags, m);
|
|
}
|
|
} else if ((key = gm_mcp_icecrew_userlist_find_key(userlist, data_tag))
|
|
!= NULL) {
|
|
for (tmp = all_values; tmp; tmp = tmp->next) {
|
|
l = gm_mcp_parse_list((gchar *)(tmp->data));
|
|
vals = g_list_append(vals, l);
|
|
}
|
|
|
|
if (strcmp(key, "rank") == 0) {
|
|
gm_mcp_icecrew_userlist_handle_ranks_states(userlist, vals, TRUE);
|
|
} else if (strcmp(key, "state") == 0) {
|
|
gm_mcp_icecrew_userlist_handle_ranks_states(userlist, vals, FALSE);
|
|
}
|
|
|
|
gm_mcp_icecrew_userlist_remove_datatag(userlist, data_tag);
|
|
} else {
|
|
gm_debug_msg(DEBUG_ALWAYS, "Datatag %s not found", data_tag);
|
|
}
|
|
|
|
for (tmp = vals; tmp; tmp = tmp->next) {
|
|
gm_mcp_list_free((GList *)(tmp->data));
|
|
}
|
|
|
|
g_list_free(vals);
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_set_session(GmMcpPackage *package, GObject *session) {
|
|
GmMcpPackageClass *parent_class = g_type_class_peek_parent(
|
|
GM_MCP_ICECREW_USERLIST_GET_CLASS(package));
|
|
gchar *icons_dir;
|
|
GmMcpPackage *playerdb;
|
|
GmMcpIcecrewUserlist *userlist = GM_MCP_ICECREW_USERLIST(package);
|
|
GmMcpSession *ses;
|
|
|
|
parent_class->set_session(package, session);
|
|
ses = GM_MCP_SESSION(session);
|
|
|
|
playerdb = gm_mcp_session_find_package(ses, "dns-nl-icecrew-playerdb");
|
|
|
|
g_return_if_fail(playerdb != NULL);
|
|
|
|
icons_dir = g_strconcat(gm_world_path(GM_MCP_SESSION_WORLD(ses)),
|
|
G_DIR_SEPARATOR_S, "icons", NULL);
|
|
userlist->priv->rank_dir = g_strconcat(icons_dir, G_DIR_SEPARATOR_S,
|
|
"ranks", NULL);
|
|
userlist->priv->state_dir = g_strconcat(icons_dir, G_DIR_SEPARATOR_S,
|
|
"states", NULL);
|
|
|
|
if (!g_file_test(icons_dir, G_FILE_TEST_EXISTS))
|
|
mkdir(icons_dir, 0755);
|
|
if (!g_file_test(userlist->priv->rank_dir, G_FILE_TEST_EXISTS))
|
|
mkdir(userlist->priv->rank_dir, 0755);
|
|
if (!g_file_test(userlist->priv->state_dir, G_FILE_TEST_EXISTS))
|
|
mkdir(userlist->priv->state_dir, 0755);
|
|
|
|
g_free(icons_dir);
|
|
|
|
g_signal_connect(playerdb, "add",
|
|
G_CALLBACK(on_gm_mcp_icecrew_userlist_add), package);
|
|
g_signal_connect(playerdb, "set",
|
|
G_CALLBACK(on_gm_mcp_icecrew_userlist_set), package);
|
|
g_signal_connect(playerdb, "delete",
|
|
G_CALLBACK(on_gm_mcp_icecrew_userlist_delete), package);
|
|
}
|
|
|
|
void
|
|
gm_mcp_icecrew_userlist_create_view(GmMcpPackage *package, GObject *parent) {
|
|
gm_mcp_userlist_view_new(package, parent);
|
|
}
|
|
|
|
/* Callbacks */
|
|
void
|
|
on_gm_mcp_icecrew_userlist_add(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, GmMcpIcecrewUserlist *userlist) {
|
|
gchar *sort = gm_mcp_icecrew_userlist_sort_string(userlist, ppi);
|
|
gchar const *name = gm_playerdb_player_info_get_prop(ppi, "P_NAME");
|
|
gchar const *icon_path = gm_mcp_icecrew_userlist_icon_path(userlist, ppi);
|
|
|
|
g_signal_emit(userlist, gm_mcp_icecrew_userlist_signals[PLAYER_ADDED],
|
|
0, ppi->id, name, icon_path, sort);
|
|
}
|
|
|
|
void
|
|
on_gm_mcp_icecrew_userlist_set(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, gchar const *key, gchar const *value,
|
|
gchar const *old, GmMcpIcecrewUserlist *userlist) {
|
|
gchar *sort = NULL;
|
|
|
|
if (strcmp(key, "P_STATE") == 0) {
|
|
sort = gm_mcp_icecrew_userlist_sort_string(userlist, ppi);
|
|
|
|
g_signal_emit(userlist, gm_mcp_icecrew_userlist_signals[STATE_CHANGED],
|
|
0, ppi->id, gm_mcp_icecrew_userlist_icon_path(userlist, ppi),
|
|
sort);
|
|
} else if (strcmp(key, "P_RANK") == 0) {
|
|
sort = gm_mcp_icecrew_userlist_sort_string(userlist, ppi);
|
|
|
|
g_signal_emit(userlist, gm_mcp_icecrew_userlist_signals[RANK_CHANGED],
|
|
0, ppi->id, gm_mcp_icecrew_userlist_icon_path(userlist, ppi),
|
|
sort);
|
|
} else if (strcmp(key, "P_NAME") == 0) {
|
|
sort = gm_mcp_icecrew_userlist_sort_string(userlist, ppi);
|
|
|
|
g_signal_emit(userlist, gm_mcp_icecrew_userlist_signals[NAME_CHANGED],
|
|
0, ppi->id, value, sort);
|
|
}
|
|
}
|
|
|
|
void
|
|
on_gm_mcp_icecrew_userlist_delete(GmMcpIcecrewPlayerdb *playerdb,
|
|
GmPlayerdbPlayerInfo *ppi, GmMcpIcecrewUserlist *userlist) {
|
|
g_signal_emit(userlist, gm_mcp_icecrew_userlist_signals[PLAYER_REMOVED],
|
|
0, ppi->id);
|
|
}
|