Initial import

This commit is contained in:
Jesse van den Kieboom 2005-11-15 11:48:19 +00:00
parent 0aa02ec4d6
commit 5271a749bb
18 changed files with 3668 additions and 0 deletions

View File

@ -0,0 +1,80 @@
#include "gm-mcp-awns-ping.h"
#include "gm-mcp.h"
#include "gm-mcp-session.h"
#define GM_MCP_AWNS_PING_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_AWNS_PING, GmMcpAwnsPingPrivate))
struct _GmMcpAwnsPingPrivate {
};
/* Signals
enum {
PROTO
NUM_SIGNALS
};
static guint gm_mcp_awns_ping_signals[NUM_SIGNALS] = {0};*/
G_DEFINE_TYPE(GmMcpAwnsPing, gm_mcp_awns_ping, GM_TYPE_MCP_PACKAGE)
void gm_mcp_awns_ping_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields);
static void
gm_mcp_awns_ping_finalize(GObject *object) {
//GmMcpAwnsPing *obj = GM_MCP_AWNS_PING(object);
G_OBJECT_CLASS(gm_mcp_awns_ping_parent_class)->finalize(object);
}
static void
gm_mcp_awns_ping_class_init(GmMcpAwnsPingClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_awns_ping_finalize;
/*gm_mcp_awns_ping_signals[PROTO] =
g_signal_new("proto",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpAwnsPingClass, proto),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);*/
pklass->name = "dns-com-awns-ping";
pklass->handle_simple = &gm_mcp_awns_ping_handle_simple;
g_type_class_add_private(object_class, sizeof(GmMcpAwnsPingPrivate));
}
static void
gm_mcp_awns_ping_init(GmMcpAwnsPing *obj) {
obj->priv = GM_MCP_AWNS_PING_GET_PRIVATE(obj);
}
GmMcpAwnsPing *
gm_mcp_awns_ping_new() {
GmMcpAwnsPing *obj = GM_MCP_AWNS_PING(g_object_new(GM_TYPE_MCP_AWNS_PING, NULL));
return obj;
}
void
gm_mcp_awns_ping_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
gchar const *id;
if (!suffix) {
if ((id = gm_mcp_find_value(fields, "id"))) {
gm_mcp_session_send_simple(GM_MCP_PACKAGE_SESSION(package),
"dns-com-awns-ping-reply", "id", id, NULL);
}
}
}

View File

@ -0,0 +1,58 @@
#ifndef __GM_MCP_AWNS_PING_H__
#define __GM_MCP_AWNS_PING_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_AWNS_PING (gm_mcp_awns_ping_get_type())
#define GM_MCP_AWNS_PING(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_AWNS_PING, GmMcpAwnsPing))
#define GM_MCP_AWNS_PING_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_AWNS_PING, GmMcpAwnsPing const))
#define GM_MCP_AWNS_PING_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_AWNS_PING, GmMcpAwnsPingClass))
#define GM_IS_MCP_AWNS_PING(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_AWNS_PING))
#define GM_IS_MCP_AWNS_PING_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_AWNS_PING))
#define GM_MCP_AWNS_PING_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_AWNS_PING, GmMcpAwnsPingClass))
/* Private structure type */
typedef struct _GmMcpAwnsPingPrivate GmMcpAwnsPingPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpAwnsPing GmMcpAwnsPing;
struct _GmMcpAwnsPing {
GmMcpPackage parent;
/*< private > */
GmMcpAwnsPingPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpAwnsPingClass GmMcpAwnsPingClass;
struct _GmMcpAwnsPingClass {
GmMcpPackageClass parent_class;
/* Signals
void (* proto) (GmMcpAwnsPing *obj); */
};
GType gm_mcp_awns_ping_get_type(void) G_GNUC_CONST;
GmMcpAwnsPing *gm_mcp_awns_ping_new(void);
G_END_DECLS
#endif /* __GM_MCP_AWNS_PING_H__ */

View File

@ -0,0 +1,72 @@
#include "gm-mcp-icecrew-mcpreset.h"
#include "gm-mcp-session.h"
#define GM_MCP_ICECREW_MCPRESET_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_ICECREW_MCPRESET, GmMcpIcecrewMcpresetPrivate))
struct _GmMcpIcecrewMcpresetPrivate {
};
/* Signals
enum {
PROTO
NUM_SIGNALS
};
static guint gm_mcp_icecrew_mcpreset_signals[NUM_SIGNALS] = {0};*/
G_DEFINE_TYPE(GmMcpIcecrewMcpreset, gm_mcp_icecrew_mcpreset, GM_TYPE_MCP_PACKAGE)
void gm_mcp_icecrew_mcpreset_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields);
static void
gm_mcp_icecrew_mcpreset_finalize(GObject *object) {
//GmMcpIcecrewMcpreset *obj = GM_MCP_ICECREW_MCPRESET(object);
G_OBJECT_CLASS(gm_mcp_icecrew_mcpreset_parent_class)->finalize(object);
}
static void
gm_mcp_icecrew_mcpreset_class_init(GmMcpIcecrewMcpresetClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_icecrew_mcpreset_finalize;
/*gm_mcp_icecrew_mcpreset_signals[PROTO] =
g_signal_new("proto",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpIcecrewMcpresetClass, proto),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);*/
pklass->name = "dns-nl-icecrew-mcpreset";
pklass->handle_simple = &gm_mcp_icecrew_mcpreset_handle_simple;
g_type_class_add_private(object_class, sizeof(GmMcpIcecrewMcpresetPrivate));
}
static void
gm_mcp_icecrew_mcpreset_init(GmMcpIcecrewMcpreset *obj) {
obj->priv = GM_MCP_ICECREW_MCPRESET_GET_PRIVATE(obj);
}
GmMcpIcecrewMcpreset *
gm_mcp_icecrew_mcpreset_new() {
GmMcpIcecrewMcpreset *obj = GM_MCP_ICECREW_MCPRESET(g_object_new(GM_TYPE_MCP_ICECREW_MCPRESET, NULL));
return obj;
}
void
gm_mcp_icecrew_mcpreset_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
gm_mcp_session_reset(GM_MCP_PACKAGE_SESSION(package));
}

View File

@ -0,0 +1,58 @@
#ifndef __GM_MCP_ICECREW_MCPRESET_H__
#define __GM_MCP_ICECREW_MCPRESET_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_ICECREW_MCPRESET (gm_mcp_icecrew_mcpreset_get_type())
#define GM_MCP_ICECREW_MCPRESET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_ICECREW_MCPRESET, GmMcpIcecrewMcpreset))
#define GM_MCP_ICECREW_MCPRESET_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_ICECREW_MCPRESET, GmMcpIcecrewMcpreset const))
#define GM_MCP_ICECREW_MCPRESET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_ICECREW_MCPRESET, GmMcpIcecrewMcpresetClass))
#define GM_IS_MCP_ICECREW_MCPRESET(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_ICECREW_MCPRESET))
#define GM_IS_MCP_ICECREW_MCPRESET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_ICECREW_MCPRESET))
#define GM_MCP_ICECREW_MCPRESET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_ICECREW_MCPRESET, GmMcpIcecrewMcpresetClass))
/* Private structure type */
typedef struct _GmMcpIcecrewMcpresetPrivate GmMcpIcecrewMcpresetPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpIcecrewMcpreset GmMcpIcecrewMcpreset;
struct _GmMcpIcecrewMcpreset {
GmMcpPackage parent;
/*< private > */
GmMcpIcecrewMcpresetPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpIcecrewMcpresetClass GmMcpIcecrewMcpresetClass;
struct _GmMcpIcecrewMcpresetClass {
GmMcpPackageClass parent_class;
/* Signals
void (* proto) (GmMcpIcecrewMcpreset *obj); */
};
GType gm_mcp_icecrew_mcpreset_get_type(void) G_GNUC_CONST;
GmMcpIcecrewMcpreset *gm_mcp_icecrew_mcpreset_new(void);
G_END_DECLS
#endif /* __GM_MCP_ICECREW_MCPRESET_H__ */

View File

@ -0,0 +1,370 @@
#include <string.h>
#include <stdlib.h>
#include "gm-mcp-icecrew-playerdb.h"
#include "gm-mcp.h"
#include "../gm-marshal.h"
#include "../gm-debug.h"
#include "../gm-support.h"
#include "../gm-string.h"
#define GM_MCP_ICECREW_PLAYERDB_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_ICECREW_PLAYERDB, GmMcpIcecrewPlayerdbPrivate))
struct _GmMcpIcecrewPlayerdbPrivate {
gint self;
GList *db;
GList *last_init_keys;
GList *signals;
};
/* Signals */
enum {
ADD,
SET,
DELETE,
NUM_SIGNALS
};
static guint gm_mcp_icecrew_playerdb_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmMcpIcecrewPlayerdb, gm_mcp_icecrew_playerdb,
GM_TYPE_MCP_PACKAGE)
void gm_mcp_icecrew_playerdb_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields);
gboolean gm_mcp_icecrew_playerdb_handle_multi(GmMcpPackage *package,
gchar const *data_tag, gchar const *key, gchar const *value,
GList *all_values);
static void
gm_mcp_icecrew_playerdb_finalize(GObject *object) {
GmMcpIcecrewPlayerdb *obj = GM_MCP_ICECREW_PLAYERDB(object);
GmPlayerdbPlayerInfo *ppi;
GList *f;
for (f = obj->priv->db; f; f = f->next) {
ppi = (GmPlayerdbPlayerInfo *)(f->data);
g_hash_table_destroy(ppi->values);
g_free(ppi);
}
g_list_free(obj->priv->db);
gm_mcp_list_free(obj->priv->last_init_keys);
G_OBJECT_CLASS(gm_mcp_icecrew_playerdb_parent_class)->finalize(object);
}
static void
gm_mcp_icecrew_playerdb_class_init(GmMcpIcecrewPlayerdbClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_icecrew_playerdb_finalize;
gm_mcp_icecrew_playerdb_signals[ADD] =
g_signal_new("add",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpIcecrewPlayerdbClass, add),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
gm_mcp_icecrew_playerdb_signals[SET] =
g_signal_new("set",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpIcecrewPlayerdbClass, set),
NULL, NULL,
gm_marshal_VOID__POINTER_STRING_STRING_STRING,
G_TYPE_NONE,
4,
G_TYPE_POINTER,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING);
gm_mcp_icecrew_playerdb_signals[DELETE] =
g_signal_new("delete",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpIcecrewPlayerdbClass, delete),
NULL, NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
G_TYPE_POINTER);
pklass->name = "dns-nl-icecrew-playerdb";
pklass->handle_simple = &gm_mcp_icecrew_playerdb_handle_simple;
pklass->handle_multi = &gm_mcp_icecrew_playerdb_handle_multi;
g_type_class_add_private(object_class, sizeof(GmMcpIcecrewPlayerdbPrivate));
}
static void
gm_mcp_icecrew_playerdb_init(GmMcpIcecrewPlayerdb *obj) {
obj->priv = GM_MCP_ICECREW_PLAYERDB_GET_PRIVATE(obj);
obj->priv->self = 0;
obj->priv->db = NULL;
obj->priv->last_init_keys = NULL;
obj->priv->signals = NULL;
}
GmMcpIcecrewPlayerdb *
gm_mcp_icecrew_playerdb_new() {
GmMcpIcecrewPlayerdb *obj = GM_MCP_ICECREW_PLAYERDB(g_object_new(
GM_TYPE_MCP_ICECREW_PLAYERDB, NULL));
return obj;
}
GmPlayerdbPlayerInfo *
gm_mcp_icecrew_playerdb_find(GmMcpIcecrewPlayerdb *package, gint id) {
GmPlayerdbPlayerInfo *ppi;
GList *item;
for (item = package->priv->db; item; item = item->next) {
ppi = (GmPlayerdbPlayerInfo *)(item->data);
if (ppi->id == id) {
return ppi;
}
}
return NULL;
}
gchar const *
gm_playerdb_player_info_get_prop(GmPlayerdbPlayerInfo *ppi, gchar const *key) {
return g_hash_table_lookup(ppi->values, key);
}
void
gm_mcp_icecrew_playerdb_find_players_with(GmMcpIcecrewPlayerdb *package,
gchar const *key, gchar const *value, PlayerdbFindFunc func,
gpointer user_data) {
GmPlayerdbPlayerInfo *ppi;
gchar const *v;
GList *db;
for (db = package->priv->db; db; db = db->next) {
ppi = (GmPlayerdbPlayerInfo *)(db->data);
v = gm_playerdb_player_info_get_prop(ppi, key);
if (v != NULL && (value == NULL || strcmp(v, value) == 0)) {
func(ppi, user_data);
}
}
}
void
gm_mcp_icecrew_playerdb_set_prop(GmMcpIcecrewPlayerdb *package,
GmPlayerdbPlayerInfo *ppi, gchar const *key, gchar const *value,
gboolean add) {
gchar *old;
if (strcmp(key, "id") == 0) {
return;
}
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewPlayerdb.SetProp: key: %s, value: %s",
key, value);
old = g_strdup(gm_playerdb_player_info_get_prop(ppi, key));
if (old && strcmp(old, value) == 0) {
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewPlayerdb.SetProp: new value is "
"the same as old value, no changes made");
g_free(old);
return;
}
g_hash_table_insert(ppi->values, g_strdup(key), g_strdup(value));
if (!add) {
g_signal_emit(package, gm_mcp_icecrew_playerdb_signals[SET], 0,
ppi, key, value, old);
}
g_free(old);
}
void
gm_mcp_icecrew_playerdb_modify_prop(GmMcpIcecrewPlayerdb *package,
GmPlayerdbPlayerInfo *ppi, gchar const *key, gchar const *value,
gboolean add) {
if (ppi) {
gm_mcp_icecrew_playerdb_set_prop(package, ppi, key, value, add);
}
}
void
gm_mcp_icecrew_playerdb_modify_prop_list(GmMcpIcecrewPlayerdb *package,
GmPlayerdbPlayerInfo *ppi, GList *fields, gboolean add) {
GmKeyValuePair *data;
if (ppi) {
for (; fields; fields = fields->next) {
data = (GmKeyValuePair *)(fields->data);
gm_mcp_icecrew_playerdb_set_prop(package, ppi, data->key,
data->value, add);
}
}
}
void
gm_mcp_icecrew_playerdb_remove_player(GmMcpIcecrewPlayerdb *package, gint id) {
GmPlayerdbPlayerInfo *ppi;
if ((ppi = gm_mcp_icecrew_playerdb_find(package, id))) {
g_signal_emit(package, gm_mcp_icecrew_playerdb_signals[DELETE], 0,
ppi);
package->priv->db = g_list_remove(package->priv->db, ppi);
g_hash_table_destroy(ppi->values);
}
}
GmPlayerdbPlayerInfo *
gm_mcp_icecrew_playerdb_add_player(GmMcpIcecrewPlayerdb *package, gint id) {
GmPlayerdbPlayerInfo *ppi = g_new(GmPlayerdbPlayerInfo, 1);
ppi->values = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, g_free);
ppi->id = id;
package->priv->db = g_list_append(package->priv->db, ppi);
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewPlayerdb.AddPlayer: adding id %d", id);
return ppi;
}
void
gm_mcp_icecrew_playerdb_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
GmMcpIcecrewPlayerdb *playerdb = GM_MCP_ICECREW_PLAYERDB(package);
gchar const *value;
GmPlayerdbPlayerInfo *ppi;
gint id, add;
if (strcasecmp(suffix, "self") == 0) {
if ((value = gm_mcp_find_value(fields, "id"))) {
playerdb->priv->self = atoi(value);
}
} else if ((add = strcasecmp(suffix, "add")) == 0 ||
strcasecmp(suffix, "set") == 0) {
if ((value = gm_mcp_find_value(fields, "id"))) {
id = atoi(value);
ppi = gm_mcp_icecrew_playerdb_find(playerdb, id);
if (add == 0 && !ppi) {
ppi = gm_mcp_icecrew_playerdb_add_player(playerdb, id);
gm_mcp_icecrew_playerdb_modify_prop_list(playerdb, ppi, fields,
TRUE);
g_signal_emit(playerdb, gm_mcp_icecrew_playerdb_signals[ADD],
0, ppi);
} else if (add != 0 && ppi) {
gm_mcp_icecrew_playerdb_modify_prop_list(playerdb, ppi, fields,
FALSE);
}
}
} else if (strcasecmp(suffix, "del") == 0) {
if ((value = gm_mcp_find_value(fields, "id"))) {
id = atoi(value);
gm_mcp_icecrew_playerdb_remove_player(playerdb, id);
}
} else if (strcasecmp(suffix, "init") == 0) {
if ((value = gm_mcp_find_value(fields, "keys"))) {
if (playerdb->priv->last_init_keys) {
gm_mcp_list_free(playerdb->priv->last_init_keys);
}
playerdb->priv->last_init_keys = gm_mcp_parse_list(value);
}
}
}
gboolean
gm_mcp_icecrew_playerdb_handle_multi(GmMcpPackage *package,
gchar const *data_tag, gchar const *key, gchar const *value,
GList *all_values) {
GmMcpIcecrewPlayerdb *playerdb = GM_MCP_ICECREW_PLAYERDB(package);
gint i;
guint counter;
gchar *id, *list;
gchar const *ptr = value;
GList *l;
GmPlayerdbPlayerInfo *ppi;
gunichar uc;
if (key != NULL) {
/* We should have a value something like <NUM> <LIST> */
gm_string_skip_space(&value);
ptr = value;
gm_string_skip_nonspace(&ptr);
if (*ptr == '\0') {
return TRUE;
}
id = g_strndup(value, ptr - value);
gm_string_skip_space(&ptr);
value = ptr;
if (g_utf8_get_char(ptr) == '"') {
ptr = g_utf8_next_char(ptr);
value = ptr;
i = 0;
while (*ptr != '\0' && (uc = g_utf8_get_char(ptr)) != '"') {
ptr = g_utf8_next_char(ptr);
if (uc == '\\' && g_utf8_get_char(ptr) != '\0') {
ptr = g_utf8_next_char(ptr);
}
}
list = g_strndup(value, ptr - value);
l = gm_mcp_parse_list(list);
if (g_list_length(l) ==
g_list_length(playerdb->priv->last_init_keys)) {
i = atoi(id);
if ((ppi = gm_mcp_icecrew_playerdb_find(playerdb, i))) {
gm_mcp_icecrew_playerdb_remove_player(playerdb, i);
}
ppi = gm_mcp_icecrew_playerdb_add_player(playerdb, i);
for (counter = 0; counter < g_list_length(l); ++counter) {
gm_mcp_icecrew_playerdb_modify_prop(playerdb, ppi,
g_list_nth_data(playerdb->priv->last_init_keys,
counter), g_list_nth_data(l, counter), TRUE);
}
g_signal_emit(playerdb, gm_mcp_icecrew_playerdb_signals[ADD],
0, ppi);
}
g_free(list);
gm_mcp_list_free(l);
}
g_free(id);
} else {
gm_mcp_list_free(playerdb->priv->last_init_keys);
playerdb->priv->last_init_keys = NULL;
}
return TRUE;
}

View File

@ -0,0 +1,74 @@
#ifndef __GM_MCP_ICECREW_PLAYERDB_H__
#define __GM_MCP_ICECREW_PLAYERDB_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_ICECREW_PLAYERDB (gm_mcp_icecrew_playerdb_get_type())
#define GM_MCP_ICECREW_PLAYERDB(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_ICECREW_PLAYERDB, GmMcpIcecrewPlayerdb))
#define GM_MCP_ICECREW_PLAYERDB_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_ICECREW_PLAYERDB, GmMcpIcecrewPlayerdb const))
#define GM_MCP_ICECREW_PLAYERDB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_ICECREW_PLAYERDB, GmMcpIcecrewPlayerdbClass))
#define GM_IS_MCP_ICECREW_PLAYERDB(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_ICECREW_PLAYERDB))
#define GM_IS_MCP_ICECREW_PLAYERDB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_ICECREW_PLAYERDB))
#define GM_MCP_ICECREW_PLAYERDB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_ICECREW_PLAYERDB, GmMcpIcecrewPlayerdbClass))
/* Private structure type */
typedef struct _GmMcpIcecrewPlayerdbPrivate GmMcpIcecrewPlayerdbPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpIcecrewPlayerdb GmMcpIcecrewPlayerdb;
struct _GmMcpIcecrewPlayerdb {
GmMcpPackage parent;
/*< private > */
GmMcpIcecrewPlayerdbPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpIcecrewPlayerdbClass GmMcpIcecrewPlayerdbClass;
struct _GmMcpIcecrewPlayerdbClass {
GmMcpPackageClass parent_class;
/* Signals */
void (* add) (GmMcpIcecrewPlayerdb *obj, gpointer player_info);
void (* set) (GmMcpIcecrewPlayerdb *obj, gpointer player_info,
gchar const *key, gchar const *value, gchar const *old_value);
void (* delete) (GmMcpIcecrewPlayerdb *obj, gpointer player_info);
};
typedef struct _GmPlayerdbPlayerInfo {
gint id;
GHashTable *values;
} GmPlayerdbPlayerInfo;
typedef void (*PlayerdbFindFunc) (GmPlayerdbPlayerInfo *, gpointer user_data);
GType gm_mcp_icecrew_playerdb_get_type(void) G_GNUC_CONST;
GmMcpIcecrewPlayerdb *gm_mcp_icecrew_playerdb_new(void);
gchar const *gm_playerdb_player_info_get_prop(GmPlayerdbPlayerInfo *ppi,
gchar const *key);
void gm_mcp_icecrew_playerdb_find_players_with(GmMcpIcecrewPlayerdb *package,
gchar const *key, gchar const *value, PlayerdbFindFunc func,
gpointer user_data);
G_END_DECLS
#endif /* __GM_MCP_ICECREW_PLAYERDB_H__ */

View File

@ -0,0 +1,388 @@
#include <string.h>
#include "gm-mcp-icecrew-serverinfo.h"
#include "gm-mcp.h"
#include "gm-mcp-session.h"
#include "../widgets/gm-app-view.h"
#include "../gm-world.h"
#include "../dialogs/gm-world-info-dialog.h"
#include "../gm-support.h"
#include "../gm-debug.h"
#include "../gm-options.h"
#define GM_MCP_ICECREW_SERVERINFO_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfoPrivate))
typedef struct _GmMcpIcecrewServerinfoView {
GmAppView *view;
GmMcpIcecrewServerinfo *package;
} GmMcpIcecrewServerinfoView;
struct _GmMcpIcecrewServerinfoPrivate {
gboolean has_info;
GmWorldInfo info;
GmFetchHandle *handle;
}action;
/* Signals */
enum {
GOT_INFO,
NUM_SIGNALS
};
static guint gm_mcp_icecrew_serverinfo_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmMcpIcecrewServerinfo, gm_mcp_icecrew_serverinfo, GM_TYPE_MCP_PACKAGE)
void gm_mcp_icecrew_serverinfo_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields);
void gm_mcp_icecrew_serverinfo_create_view(GmMcpPackage *package,
GObject *parent);
void gm_mcp_icecrew_serverinfo_set_session(GmMcpPackage *package,
GObject *session);
void
gm_mcp_icecrew_serverinfo_free_info(GmMcpIcecrewServerinfo *obj) {
g_free(obj->priv->info.homepage);
g_free(obj->priv->info.location);
g_free(obj->priv->info.admin);
g_free(obj->priv->info.contact);
g_free(obj->priv->info.charset);
g_free(obj->priv->info.language);
g_free(obj->priv->info.system);
g_free(obj->priv->info.logo);
if (obj->priv->handle) {
obj->priv->handle->aborted = TRUE;
}
memset(&(obj->priv->info), 0, sizeof(GmWorldInfo));
}
static void
gm_mcp_icecrew_serverinfo_finalize(GObject *object) {
GmMcpIcecrewServerinfo *obj = GM_MCP_ICECREW_SERVERINFO(object);
gm_mcp_icecrew_serverinfo_free_info(obj);
G_OBJECT_CLASS(gm_mcp_icecrew_serverinfo_parent_class)->finalize(object);
}
static void
gm_mcp_icecrew_serverinfo_class_init(GmMcpIcecrewServerinfoClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_icecrew_serverinfo_finalize;
gm_mcp_icecrew_serverinfo_signals[GOT_INFO] =
g_signal_new("got_info",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpIcecrewServerinfoClass, got_info),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
pklass->name = "dns-nl-icecrew-serverinfo";
pklass->handle_simple = &gm_mcp_icecrew_serverinfo_handle_simple;
pklass->create_view = &gm_mcp_icecrew_serverinfo_create_view;
pklass->set_session = &gm_mcp_icecrew_serverinfo_set_session;
g_type_class_add_private(object_class, sizeof(GmMcpIcecrewServerinfoPrivate));
}
static void
gm_mcp_icecrew_serverinfo_init(GmMcpIcecrewServerinfo *obj) {
obj->priv = GM_MCP_ICECREW_SERVERINFO_GET_PRIVATE(obj);
obj->priv->has_info = FALSE;
}
GmMcpIcecrewServerinfo *
gm_mcp_icecrew_serverinfo_new() {
GmMcpIcecrewServerinfo *obj = GM_MCP_ICECREW_SERVERINFO(g_object_new( \
GM_TYPE_MCP_ICECREW_SERVERINFO, NULL));
return obj;
}
void
gm_mcp_icecrew_serverinfo_fetch_progress(GmFetchHandle *g,
GmMcpIcecrewServerinfo *package) {
gchar *path;
GdkPixbuf *pixtest;
GError *err = NULL;
if (g->aborted) {
if (GM_IS_MCP_ICECREW_SERVERINFO(package)) {
package->priv->handle = NULL;
}
gm_debug_msg(DEBUG_MCP, "GmIcecrewServerInfo.FetchProgress: "
"fetch aborted!");
return;
}
if (g->done) {
if (GM_IS_MCP_ICECREW_SERVERINFO(package)) {
package->priv->handle = NULL;
}
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: "
"fetch done!");
return;
}
if (g->cur_phase == GNOME_VFS_XFER_PHASE_FILECOMPLETED) {
path = gnome_vfs_get_local_path_from_uri(g->cur_file_name);
pixtest = gdk_pixbuf_new_from_file(path, &err);
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: %s "
"fetched!", path);
if (pixtest) {
g_object_unref(pixtest);
package->priv->info.logo = path;
gm_options_set(gm_world_options(GM_MCP_SESSION_WORLD(
GM_MCP_PACKAGE_SESSION(package))), "logo", path);
g_signal_emit(package,
gm_mcp_icecrew_serverinfo_signals[GOT_INFO], 0);
g->aborted = TRUE;
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.FetchProgress: "
"Error on loading %s: %s", path, err->message);
g_error_free(err);
g_free(path);
}
}
}
void
gm_mcp_icecrew_serverinfo_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
GmMcpIcecrewServerinfo *serverinfo = GM_MCP_ICECREW_SERVERINFO(package);
gchar *base, *path, **alternatives, **ptr;
gchar const *logo;
GList *source = NULL, *dest = NULL;
GnomeVFSResult result;
GnomeVFSFileInfo *finfo;
if (strcmp(suffix, "set") == 0) {
gm_mcp_icecrew_serverinfo_free_info(serverinfo);
serverinfo->priv->info.name =
g_strdup(gm_mcp_find_value(fields, "name"));
serverinfo->priv->info.homepage =
g_strdup(gm_mcp_find_value(fields, "homepage"));
serverinfo->priv->info.location =
g_strdup(gm_mcp_find_value(fields, "location"));
serverinfo->priv->info.admin =
g_strdup(gm_mcp_find_value(fields, "admin"));
serverinfo->priv->info.contact =
g_strdup(gm_mcp_find_value(fields, "contact"));
serverinfo->priv->info.charset =
g_strdup(gm_mcp_find_value(fields, "charset"));
serverinfo->priv->info.language =
g_strdup(gm_mcp_find_value(fields, "language"));
serverinfo->priv->info.system =
g_strdup(gm_mcp_find_value(fields, "system"));
gm_options_set(gm_world_options(GM_MCP_SESSION_WORLD(
GM_MCP_PACKAGE_SESSION(package))), "mooname",
serverinfo->priv->info.name);
if ((logo = gm_mcp_find_value(fields, "logo")) != NULL) {
alternatives = g_strsplit(logo, ";", 0);
ptr = alternatives;
while (*ptr) {
finfo = gnome_vfs_file_info_new();
result = gnome_vfs_get_file_info(*ptr, finfo,
GNOME_VFS_FILE_INFO_DEFAULT);
gnome_vfs_file_info_unref(finfo);
if (result != GNOME_VFS_OK) {
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewServerinfo.HandleSimple: "
"Ignore logo alternative %s because it's invalid: %s",
*ptr, gnome_vfs_result_to_string(result));
} else {
base = g_path_get_basename(*ptr);
if (base && *base != '\0' && base[1] != '\0') {
path = g_strconcat(gm_world_path(GM_MCP_SESSION_WORLD(
GM_MCP_PACKAGE_SESSION(package))),
G_DIR_SEPARATOR_S, "pixmaps", G_DIR_SEPARATOR_S,
base, NULL);
source = g_list_append(source, g_strdup(*ptr));
dest = g_list_append(dest, path);
}
g_free(base);
}
++ptr;
}
g_strfreev(alternatives);
if (source != NULL) {
if (serverinfo->priv->handle) {
serverinfo->priv->handle->aborted = TRUE;
while (serverinfo->priv->handle != NULL) {
gm_do_events();
}
}
if (serverinfo->priv->info.logo) {
if (g_file_test(serverinfo->priv->info.logo,
G_FILE_TEST_EXISTS)) {
unlink(serverinfo->priv->info.logo);
}
g_free(serverinfo->priv->info.logo);
serverinfo->priv->info.logo = NULL;
}
gm_fetch(source, dest,
(GFunc)gm_mcp_icecrew_serverinfo_fetch_progress,
serverinfo);
gm_g_list_free_simple(source);
gm_g_list_free_simple(dest);
}
}
serverinfo->priv->has_info = TRUE;
g_signal_emit(serverinfo, gm_mcp_icecrew_serverinfo_signals[GOT_INFO],
0);
}
}
void
gm_mcp_icecrew_serverinfo_set_session(GmMcpPackage *package, GObject *session) {
GmMcpPackageClass *parent_class = g_type_class_peek_parent(
GM_MCP_ICECREW_SERVERINFO_GET_CLASS(package));
gchar *path;
parent_class->set_session(package, session);
path = g_strconcat(gm_world_path(GM_MCP_SESSION_WORLD(
GM_MCP_SESSION(session))), G_DIR_SEPARATOR_S, "pixmaps", NULL);
if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
mkdir(path, 0755);
}
g_free(path);
gm_mcp_session_send_simple(GM_MCP_SESSION(session),
"dns-nl-icecrew-serverinfo-get", NULL);
}
gboolean
gm_mcp_icecrew_serverinfo_has_info(GmMcpIcecrewServerinfo *package) {
return package->priv->has_info;
}
GmWorldInfo const *
gm_mcp_icecrew_serverinfo_info(GmMcpIcecrewServerinfo *package) {
return &(package->priv->info);
}
/* GmMcpIcecrewServerinfoView */
void
on_gm_mcp_icecrew_serverinfo_view_activate(GtkMenuItem *item,
GmMcpIcecrewServerinfoView *view) {
gm_world_info_dialog_new(gm_mcp_icecrew_serverinfo_info(view->package));
}
void
gm_mcp_icecrew_serverinfo_view_set_sensitive(GmMcpIcecrewServerinfoView *view,
gboolean sensitive) {
GtkAction *action = gm_app_view_action(view->view,
"/MenuBar/WorldMenu/WorldInfoMenu");
if (gtk_action_get_sensitive(action) == sensitive) {
return;
}
gtk_action_set_sensitive(action, sensitive);
if (sensitive) {
g_signal_connect(action, "activate",
G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_activate), view);
} else {
g_signal_handlers_disconnect_by_func(action,
on_gm_mcp_icecrew_serverinfo_view_activate, view);
}
}
void
on_gm_mcp_icecrew_serverinfo_view_active_changed(GmWorld *world,
gboolean active, GmMcpIcecrewServerinfoView *view) {
if (active && gm_mcp_icecrew_serverinfo_has_info(view->package)) {
gm_mcp_icecrew_serverinfo_view_set_sensitive(view, TRUE);
} else if (!active) {
gm_mcp_icecrew_serverinfo_view_set_sensitive(view, FALSE);
}
}
void
on_gm_mcp_icecrew_serverinfo_view_weak_notify(gpointer data, GObject *obj) {
GmMcpIcecrewServerinfoView *view = (GmMcpIcecrewServerinfoView *)(data);
GmWorld *world = GM_MCP_SESSION_WORLD(
GM_MCP_PACKAGE_SESSION(view->package));
g_signal_handlers_disconnect_by_func(world,
on_gm_mcp_icecrew_serverinfo_view_active_changed, view);
if (gm_world_active(world)) {
gm_mcp_icecrew_serverinfo_view_set_sensitive(view, FALSE);
}
g_free(data);
}
void on_gm_mcp_icecrew_serverinfo_view_got_info(GmMcpIcecrewServerinfo *package,
GmMcpIcecrewServerinfoView *view) {
if (gm_world_active(GM_MCP_SESSION_WORLD(
GM_MCP_PACKAGE_SESSION(package)))) {
gm_mcp_icecrew_serverinfo_view_set_sensitive(view, TRUE);
}
// TODO: set logo for world menu item
}
void
gm_mcp_icecrew_serverinfo_create_view(GmMcpPackage *package, GObject *parent) {
GmMcpIcecrewServerinfoView *view;
if (!GM_IS_APP_VIEW(parent)) {
return;
}
view = g_new(GmMcpIcecrewServerinfoView, 1);
view->view = GM_APP_VIEW(parent);
view->package = GM_MCP_ICECREW_SERVERINFO(package);
// Connect the got_info signal to know when new information has arrived
g_signal_connect(package, "got_info",
G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_got_info), view);
// Connect to active_changed signal of the world to alter the sensitivity
// of the info menu item
g_signal_connect(GM_MCP_SESSION_WORLD(GM_MCP_PACKAGE_SESSION(package)),
"active_changed",
G_CALLBACK(on_gm_mcp_icecrew_serverinfo_view_active_changed),
view);
// Connect a weak ref notifier to the McpPackage to know when to destroy
// ourselfs
g_object_weak_ref(G_OBJECT(package),
on_gm_mcp_icecrew_serverinfo_view_weak_notify, view);
}

View File

@ -0,0 +1,58 @@
#ifndef __GM_MCP_ICECREW_SERVERINFO_H__
#define __GM_MCP_ICECREW_SERVERINFO_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_ICECREW_SERVERINFO (gm_mcp_icecrew_serverinfo_get_type())
#define GM_MCP_ICECREW_SERVERINFO(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfo))
#define GM_MCP_ICECREW_SERVERINFO_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfo const))
#define GM_MCP_ICECREW_SERVERINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfoClass))
#define GM_IS_MCP_ICECREW_SERVERINFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_ICECREW_SERVERINFO))
#define GM_IS_MCP_ICECREW_SERVERINFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_ICECREW_SERVERINFO))
#define GM_MCP_ICECREW_SERVERINFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_ICECREW_SERVERINFO, GmMcpIcecrewServerinfoClass))
/* Private structure type */
typedef struct _GmMcpIcecrewServerinfoPrivate GmMcpIcecrewServerinfoPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpIcecrewServerinfo GmMcpIcecrewServerinfo;
struct _GmMcpIcecrewServerinfo {
GmMcpPackage parent;
/*< private > */
GmMcpIcecrewServerinfoPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpIcecrewServerinfoClass GmMcpIcecrewServerinfoClass;
struct _GmMcpIcecrewServerinfoClass {
GmMcpPackageClass parent_class;
/* Signals */
void (* got_info) (GmMcpIcecrewServerinfo *obj);
};
GType gm_mcp_icecrew_serverinfo_get_type(void) G_GNUC_CONST;
GmMcpIcecrewServerinfo *gm_mcp_icecrew_serverinfo_new(void);
G_END_DECLS
#endif /* __GM_MCP_ICECREW_SERVERINFO_H__ */

View File

@ -0,0 +1,990 @@
#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);
}

View File

@ -0,0 +1,71 @@
#ifndef __GM_MCP_ICECREW_USERLIST_H__
#define __GM_MCP_ICECREW_USERLIST_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_ICECREW_USERLIST \
(gm_mcp_icecrew_userlist_get_type())
#define GM_MCP_ICECREW_USERLIST(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GM_TYPE_MCP_ICECREW_USERLIST, \
GmMcpIcecrewUserlist))
#define GM_MCP_ICECREW_USERLIST_CONST(obj) \
(G_TYPE_CHECK_INSTANCE_CAST((obj), GM_TYPE_MCP_ICECREW_USERLIST, \
GmMcpIcecrewUserlist const))
#define GM_MCP_ICECREW_USERLIST_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), GM_TYPE_MCP_ICECREW_USERLIST, \
GmMcpIcecrewUserlistClass))
#define GM_IS_MCP_ICECREW_USERLIST(obj) \
(G_TYPE_CHECK_INSTANCE_TYPE((obj), GM_TYPE_MCP_ICECREW_USERLIST))
#define GM_IS_MCP_ICECREW_USERLIST_CLASS(klass) \
(G_TYPE_CHECK_CLASS_TYPE ((klass), GM_TYPE_MCP_ICECREW_USERLIST))
#define GM_MCP_ICECREW_USERLIST_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), GM_TYPE_MCP_ICECREW_USERLIST, \
GmMcpIcecrewUserlistClass))
/* Private structure type */
typedef struct _GmMcpIcecrewUserlistPrivate GmMcpIcecrewUserlistPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpIcecrewUserlist GmMcpIcecrewUserlist;
struct _GmMcpIcecrewUserlist {
GmMcpPackage parent;
/*< private > */
GmMcpIcecrewUserlistPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpIcecrewUserlistClass GmMcpIcecrewUserlistClass;
struct _GmMcpIcecrewUserlistClass {
GmMcpPackageClass parent_class;
/* Signals */
void (* player_added) (GmMcpIcecrewUserlist *obj, gint id,
gchar const *name, gchar const *icon, gchar const *sort);
void (* player_removed) (GmMcpIcecrewUserlist *obj, gint id);
void (* name_changed) (GmMcpIcecrewUserlist *obj, gint id,
gchar const *name, gchar const *sort);
void (* state_changed) (GmMcpIcecrewUserlist *obj, gint id,
gchar const *icon, gchar const *sort);
void (* rank_changed) (GmMcpIcecrewUserlist *obj, gint id,
gchar const *icon, gchar const *sort);
};
GType gm_mcp_icecrew_userlist_get_type(void) G_GNUC_CONST;
GmMcpIcecrewUserlist *gm_mcp_icecrew_userlist_new(void);
G_END_DECLS
#endif /* __GM_MCP_ICECREW_USERLIST_H__ */

View File

@ -0,0 +1,154 @@
#include "gm-mcp-mud-moo-simpleedit.h"
#include "gm-mcp-session.h"
#include "gm-mcp.h"
#include "../gm-debug.h"
#include "../gm-world.h"
#include "../gm-editor.h"
#define GM_MCP_MUD_MOO_SIMPLEEDIT_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, GmMcpMudMooSimpleeditPrivate))
struct _GmMcpMudMooSimpleeditPrivate {
gchar *ref;
gchar *name;
gchar *type;
};
/* Signals
enum {
PROTO
NUM_SIGNALS
};
static guint gm_mcp_mud_moo_simpleedit_signals[NUM_SIGNALS] = {0};*/
G_DEFINE_TYPE(GmMcpMudMooSimpleedit, gm_mcp_mud_moo_simpleedit, GM_TYPE_MCP_PACKAGE)
void gm_mcp_mud_moo_simpleedit_handle_simple(GmMcpPackage *package,
gchar *suffix, GList *fields);
gboolean gm_mcp_mud_moo_simpleedit_handle_multi(GmMcpPackage *package,
gchar const *data_tag, gchar const *key, gchar const *value,
GList *all_values);
void on_gm_mcp_mud_moo_simpleedit_editor_save(GmEditor *editor,
GmMcpMudMooSimpleedit *package);
static void
gm_mcp_mud_moo_simpleedit_finalize(GObject *object) {
GmMcpMudMooSimpleedit *obj = GM_MCP_MUD_MOO_SIMPLEEDIT(object);
g_free(obj->priv->ref);
g_free(obj->priv->name);
g_free(obj->priv->type);
G_OBJECT_CLASS(gm_mcp_mud_moo_simpleedit_parent_class)->finalize(object);
}
static void
gm_mcp_mud_moo_simpleedit_class_init(GmMcpMudMooSimpleeditClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_mud_moo_simpleedit_finalize;
/*gm_mcp_mud_moo_simpleedit_signals[PROTO] =
g_signal_new("proto",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpMudMooSimpleeditClass, proto),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);*/
pklass->name = "dns-org-mud-moo-simpleedit";
pklass->handle_simple = &gm_mcp_mud_moo_simpleedit_handle_simple;
pklass->handle_multi = &gm_mcp_mud_moo_simpleedit_handle_multi;
g_type_class_add_private(object_class, sizeof(GmMcpMudMooSimpleeditPrivate));
}
static void
gm_mcp_mud_moo_simpleedit_init(GmMcpMudMooSimpleedit *obj) {
obj->priv = GM_MCP_MUD_MOO_SIMPLEEDIT_GET_PRIVATE(obj);
}
GmMcpMudMooSimpleedit *
gm_mcp_mud_moo_simpleedit_new() {
GmMcpMudMooSimpleedit *obj = GM_MCP_MUD_MOO_SIMPLEEDIT(g_object_new(GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, NULL));
return obj;
}
void
gm_mcp_mud_moo_simpleedit_handle_simple(GmMcpPackage *package,
gchar *suffix, GList *fields) {
gchar const *name, *ref, *type;
GmMcpMudMooSimpleedit *simpleedit = GM_MCP_MUD_MOO_SIMPLEEDIT(package);
if (g_strcasecmp(suffix, "content") == 0) {
if (!(name = gm_mcp_find_value(fields, "name"))) {
gm_debug_msg(DEBUG_MCP, "GmMcpMooMudSimpleedit.HandleSimple: "
"no name found, ignoring!");
} else if (!(ref = gm_mcp_find_value(fields, "reference"))) {
gm_debug_msg(DEBUG_MCP, "GmMcpMooMudSimpleedit.HandleSimple: "
"no reference found, ignoring!");
} else if (!(type = gm_mcp_find_value(fields, "type"))) {
gm_debug_msg(DEBUG_MCP, "GmMcpMooMudSimpleedit.HandleSimple: "
"no type found, ignoring!");
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpMooMudSimpleedit.HandleSimple: "
"accept content: name = %s, reference = %s, type = %s",
name, ref, type);
simpleedit->priv->name = g_strdup(name);
simpleedit->priv->ref = g_strdup(ref);
simpleedit->priv->type = g_strdup(type);
}
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpMooMudSimpleedit.HandleSimple: "
"unknown suffix: %s", suffix);
}
}
gboolean
gm_mcp_mud_moo_simpleedit_handle_multi(GmMcpPackage *package,
gchar const *data_tag, gchar const *key, gchar const *value,
GList *all_values) {
GmEditor *editor;
GmMcpMudMooSimpleedit *simpleedit = GM_MCP_MUD_MOO_SIMPLEEDIT(package);
if (key) {
return FALSE;
} else {
// All values arrived! Yeah!
editor = gm_editor_new_mcp(simpleedit->priv->name,
simpleedit->priv->ref, simpleedit->priv->type, all_values);
g_signal_connect(editor, "save",
G_CALLBACK(on_gm_mcp_mud_moo_simpleedit_editor_save), package);
gm_world_add_editor(GM_MCP_SESSION_WORLD(GM_MCP_PACKAGE_SESSION(
package)), editor);
}
return TRUE;
}
/* Callbacks */
void
on_gm_mcp_mud_moo_simpleedit_editor_save(GmEditor *editor,
GmMcpMudMooSimpleedit *package) {
GmMcpSession *session = GM_MCP_PACKAGE_SESSION(package);
gchar *data_tag = gm_mcp_generate_data_tag();
if (session) {
gm_mcp_session_send_simple(session, "dns-org-mud-moo-simpleedit-set",
"reference", gm_editor_upload_cmd(editor), "type",
gm_editor_mcp_type(editor), "content*", "", "_data-tag",
data_tag, NULL);
gm_mcp_session_send_multiline(session, data_tag, "content",
gm_editor_lines(editor));
}
g_free(data_tag);
}

View File

@ -0,0 +1,58 @@
#ifndef __GM_MCP_MUD_MOO_SIMPLEEDIT_H__
#define __GM_MCP_MUD_MOO_SIMPLEEDIT_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT (gm_mcp_mud_moo_simpleedit_get_type())
#define GM_MCP_MUD_MOO_SIMPLEEDIT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, GmMcpMudMooSimpleedit))
#define GM_MCP_MUD_MOO_SIMPLEEDIT_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, GmMcpMudMooSimpleedit const))
#define GM_MCP_MUD_MOO_SIMPLEEDIT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, GmMcpMudMooSimpleeditClass))
#define GM_IS_MCP_MUD_MOO_SIMPLEEDIT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT))
#define GM_IS_MCP_MUD_MOO_SIMPLEEDIT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT))
#define GM_MCP_MUD_MOO_SIMPLEEDIT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_MUD_MOO_SIMPLEEDIT, GmMcpMudMooSimpleeditClass))
/* Private structure type */
typedef struct _GmMcpMudMooSimpleeditPrivate GmMcpMudMooSimpleeditPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpMudMooSimpleedit GmMcpMudMooSimpleedit;
struct _GmMcpMudMooSimpleedit {
GmMcpPackage parent;
/*< private > */
GmMcpMudMooSimpleeditPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpMudMooSimpleeditClass GmMcpMudMooSimpleeditClass;
struct _GmMcpMudMooSimpleeditClass {
GmMcpPackageClass parent_class;
/* Signals
void (* proto) (GmMcpMudMooSimpleedit *obj); */
};
GType gm_mcp_mud_moo_simpleedit_get_type(void) G_GNUC_CONST;
GmMcpMudMooSimpleedit *gm_mcp_mud_moo_simpleedit_new(void);
G_END_DECLS
#endif /* __GM_MCP_MUD_MOO_SIMPLEEDIT_H__ */

View File

@ -0,0 +1,275 @@
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
#include "gm-mcp-userlist-view.h"
#include "../widgets/gm-world-view.h"
#include "../gm-pixbuf.h"
#include "../gm-debug.h"
#define GM_USERLIST_ICON_SIZE 22
enum {
GM_USERLIST_ICON,
GM_USERLIST_NAME,
GM_USERLIST_ID,
GM_USERLIST_SORT,
GM_USERLIST_N_COLUMNS
};
typedef struct _GmMcpUserlistView {
GmWorldView *view;
GmMcpPackage *package;
GtkTreeModel *model;
GtkListStore *store;
GtkTreeView *tree_view;
GtkScrolledWindow *scrolled_window;
} GmMcpUserlistView;
void on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj);
void on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
gchar const *name, gchar const *icon, gchar const *sort,
GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
gchar const *name, gchar const *sort, GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view);
GtkTreeModel *
gm_mcp_userlist_view_model_create(GmMcpUserlistView *view) {
GtkListStore *store = gtk_list_store_new(GM_USERLIST_N_COLUMNS,
GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
GtkTreeModel *model = gtk_tree_model_sort_new_with_model(GTK_TREE_MODEL(
store));
view->store = store;
view->model = model;
return model;
}
GtkWidget *
gm_mcp_userlist_view_create_userlist(GmMcpUserlistView *view) {
GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);
GtkTreeModel *model = gm_mcp_userlist_view_model_create(view);
GtkWidget *tree_view = gtk_tree_view_new_with_model(model);
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window),
GTK_SHADOW_IN);
gtk_widget_set_size_request(scrolled_window, 150, -1);
gtk_widget_set_size_request(tree_view, 150, -1);
gtk_container_add(GTK_CONTAINER(scrolled_window), tree_view);
renderer = gtk_cell_renderer_pixbuf_new();
column = gtk_tree_view_column_new_with_attributes(_("I"), renderer,
"pixbuf", GM_USERLIST_ICON, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
gtk_tree_view_column_set_min_width(column, 30);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer,
"text", GM_USERLIST_NAME, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(tree_view), column);
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
GM_USERLIST_SORT, GTK_SORT_ASCENDING);
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(tree_view), GTK_CAN_FOCUS);
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree_view));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
view->tree_view = GTK_TREE_VIEW(tree_view);
view->scrolled_window = GTK_SCROLLED_WINDOW(scrolled_window);
return scrolled_window;
}
void
gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent) {
GmMcpUserlistView *view;
GtkPaned *paned;
GtkWidget *vbox, *child;
if (!GM_IS_WORLD_VIEW(parent)) {
return;
}
view = g_new(GmMcpUserlistView, 1);
view->view = GM_WORLD_VIEW(parent);
view->package = package;
paned = GTK_PANED(gm_world_view_hpaned(view->view));
vbox = gtk_paned_get_child2(paned);
if (vbox == NULL) {
vbox = gtk_vbox_new(FALSE, 6);
gtk_paned_pack2(paned, vbox, FALSE, TRUE);
}
child = gm_mcp_userlist_view_create_userlist(view);
gtk_box_pack_end(GTK_BOX(vbox), child, TRUE, TRUE, 0);
gtk_widget_show_all(vbox);
g_signal_connect(package, "player_added",
G_CALLBACK(on_gm_mcp_userlist_view_player_added), view);
g_signal_connect(package, "player_removed",
G_CALLBACK(on_gm_mcp_userlist_view_player_removed), view);
g_signal_connect(package, "name_changed",
G_CALLBACK(on_gm_mcp_userlist_view_name_changed), view);
g_signal_connect(package, "state_changed",
G_CALLBACK(on_gm_mcp_userlist_view_state_changed), view);
g_signal_connect(package, "rank_changed",
G_CALLBACK(on_gm_mcp_userlist_view_rank_changed), view);
g_object_weak_ref(G_OBJECT(package), on_gm_mcp_userlist_view_weak_notify,
view);
}
/* Callbacks */
void
on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj) {
GmMcpUserlistView *view = (GmMcpUserlistView *)(data);
GtkWidget *vbox;
GList *children;
if (GM_IS_WORLD_VIEW(view->view)) {
GM_DEBUG("Destroying scrolled window!");
gtk_widget_destroy(GTK_WIDGET(view->scrolled_window));
vbox = gtk_paned_get_child2(GTK_PANED(gm_world_view_hpaned(
view->view)));
if (vbox != NULL) {
GM_DEBUG("VBox is still there!");
children = gtk_container_get_children(GTK_CONTAINER(vbox));
if (children == NULL) {
GM_DEBUG("VBox is empty, remove it!");
gtk_widget_destroy(vbox);
}
g_list_free(children);
}
}
g_free(data);
}
gboolean
gm_mcp_userlist_view_find(GmMcpUserlistView *view, gint id, GtkTreeIter *iter) {
GtkTreeModel *model = GTK_TREE_MODEL(view->store);
gint iterid;
if (gtk_tree_model_get_iter_first(model, iter)) {
do {
gtk_tree_model_get(model, iter, GM_USERLIST_ID, &iterid, -1);
if (iterid == id) {
return TRUE;
}
} while (gtk_tree_model_iter_next(model, iter));
}
return FALSE;
}
void
on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
gchar const *name, gchar const *icon, gchar const *sort,
GmMcpUserlistView *view) {
GtkTreeIter iter;
if (gm_mcp_userlist_view_find(view, id, &iter)) {
gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnPlayerAdded: player %d "
"is already in the list, can't be added twice!", id);
return;
}
gtk_list_store_append(view->store, &iter);
gtk_list_store_set(view->store, &iter, GM_USERLIST_ID, id, GM_USERLIST_ICON,
gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE,
GM_USERLIST_ICON_SIZE), GM_USERLIST_NAME, name, GM_USERLIST_SORT,
sort, -1);
}
void
on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
GmMcpUserlistView *view) {
GtkTreeIter iter;
if (!gm_mcp_userlist_view_find(view, id, &iter)) {
gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnPlayerRemoved: player %d "
"is not in the list, can't be removed!", id);
return;
}
gtk_list_store_remove(view->store, &iter);
}
void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
gchar const *name, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
if (!gm_mcp_userlist_view_find(view, id, &iter)) {
gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnNameChanged: player %d "
"is not in the list!", id);
return;
}
gtk_list_store_set(view->store, &iter, GM_USERLIST_NAME, name, -1);
if (sort) {
gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1);
}
}
void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
if (!gm_mcp_userlist_view_find(view, id, &iter)) {
gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnRankChanged: player %d "
"is not in the list!", id);
return;
}
gtk_list_store_set(view->store, &iter, GM_USERLIST_ICON,
gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE,
GM_USERLIST_ICON_SIZE), -1);
if (sort) {
gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1);
}
}
void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
if (!gm_mcp_userlist_view_find(view, id, &iter)) {
gm_debug_msg(DEBUG_MCP, "GmMcpUserlistView.OnStateChanged: player %d "
"is not in the list!", id);
return;
}
gtk_list_store_set(view->store, &iter, GM_USERLIST_ICON,
gm_pixbuf_get_at_size(icon, GM_USERLIST_ICON_SIZE,
GM_USERLIST_ICON_SIZE), -1);
if (sort) {
gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1);
}
}

View File

@ -0,0 +1,17 @@
typedef enum _PlayerStateMask {
USERLIST_STATE_IDLE = 1 << 0,
USERLIST_STATE_BUSY = 1 << 1,
USERLIST_STATE_AWAY = 1 << 2
} PlayerStateMask;
typedef enum _UserlistEvent {
USERLIST_EVENT_NONE = 0,
USERLIST_EVENT_ONLINE = 1 << 0,
USERLIST_EVENT_OFFLINE = 1 << 1,
USERLIST_EVENT_IDLE_ON = 1 << 2,
USERLIST_EVENT_IDLE_OFF = 1 << 3,
USERLIST_EVENT_AWAY_ON = 1 << 4,
USERLIST_EVENT_AWAY_OFF = 1 << 5
} UserlistEvent;
void gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent);

View File

@ -0,0 +1,198 @@
#include "gm-mcp-vmoo-client.h"
#include "gm-mcp-session.h"
#include "../widgets/gm-world-view.h"
#include "../widgets/gm-world-text-view.h"
#define GM_MCP_VMOO_CLIENT_GET_PRIVATE(object)( \
G_TYPE_INSTANCE_GET_PRIVATE((object), \
GM_TYPE_MCP_VMOO_CLIENT, GmMcpVmooClientPrivate))
struct _GmMcpVmooClientPrivate {
};
typedef struct _GmMcpVmooClientView {
GmMcpVmooClient *package;
GmWorldTextView *view;
guint width;
guint height;
guint margin_width;
guint margin_height;
} GmMcpVmooClientView;
/* Signals
enum {
PROTO
NUM_SIGNALS
};
static guint gm_mcp_vmoo_client_signals[NUM_SIGNALS] = {0};*/
G_DEFINE_TYPE(GmMcpVmooClient, gm_mcp_vmoo_client, GM_TYPE_MCP_PACKAGE)
void gm_mcp_vmoo_client_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields);
void gm_mcp_vmoo_client_create_view(GmMcpPackage *package, GObject *parent);
void gm_mcp_vmoo_client_set_session(GmMcpPackage *package, GObject *session);
static void
gm_mcp_vmoo_client_finalize(GObject *object) {
//GmMcpVmooClient *obj = GM_MCP_VMOO_CLIENT(object);
G_OBJECT_CLASS(gm_mcp_vmoo_client_parent_class)->finalize(object);
}
static void
gm_mcp_vmoo_client_class_init(GmMcpVmooClientClass *klass) {
GObjectClass *object_class = G_OBJECT_CLASS(klass);
GmMcpPackageClass *pklass = GM_MCP_PACKAGE_CLASS(klass);
object_class->finalize = gm_mcp_vmoo_client_finalize;
/*gm_mcp_vmoo_client_signals[PROTO] =
g_signal_new("proto",
G_OBJECT_CLASS_TYPE(object_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(GmMcpVmooClientClass, proto),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);*/
pklass->name = "dns-com-vmoo-client";
pklass->set_session = &gm_mcp_vmoo_client_set_session;
pklass->handle_simple = &gm_mcp_vmoo_client_handle_simple;
pklass->create_view = &gm_mcp_vmoo_client_create_view;
g_type_class_add_private(object_class, sizeof(GmMcpVmooClientPrivate));
}
static void
gm_mcp_vmoo_client_init(GmMcpVmooClient *obj) {
obj->priv = GM_MCP_VMOO_CLIENT_GET_PRIVATE(obj);
}
GmMcpVmooClient *
gm_mcp_vmoo_client_new() {
GmMcpVmooClient *obj = GM_MCP_VMOO_CLIENT(g_object_new(GM_TYPE_MCP_VMOO_CLIENT, NULL));
return obj;
}
void
gm_mcp_vmoo_client_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
}
void
gm_mcp_vmoo_client_set_session(GmMcpPackage *package, GObject *session) {
GmMcpPackageClass *parent_class = g_type_class_peek_parent(
GM_MCP_VMOO_CLIENT_GET_CLASS(package));
parent_class->set_session(package, session);
gm_mcp_session_send_simple(GM_MCP_SESSION(session),
"dns-com-vmoo-client-info", "name", "GnoeMoe",
"text-version", VERSION, "internal-version", IVERSION,
"reg-id", "0", "flags", "", NULL);
}
/* GmMcpVmooClientView */
void
gm_mcp_vmoo_client_view_update_metrics(GmMcpVmooClientView *view) {
guint width, height, cwidth, cheight;
gchar *w, *h;
GtkAllocation *allocation = &(GTK_WIDGET(view->view)->allocation);
width = (allocation->width - view->margin_width);
height = (allocation->height - view->margin_width);
gm_world_text_view_get_metrics(view->view, &cwidth, &cheight);
if ((width % cwidth) != 0) {
width = (width / cwidth);
} else {
width = (width / cwidth) - 1;
}
if ((height % cheight) != 0) {
height = (height / cheight);
} else {
height = (height / cheight) - 1;
}
if (view->width != width || view->height != height) {
w = g_strdup_printf("%d", width);
h = g_strdup_printf("%d", height);
gm_mcp_session_send_simple(GM_MCP_PACKAGE_SESSION(view->package),
"dns-com-vmoo-client-screensize", "cols", w, "rows", h, NULL);
g_free(w);
g_free(h);
view->width = width;
view->height = height;
}
}
void
on_gm_mcp_vmoo_client_text_view_size_allocate(GtkWidget *widget,
GtkAllocation *allocation, GmMcpVmooClientView *view) {
gm_mcp_vmoo_client_view_update_metrics(view);
}
void
on_gm_mcp_vmoo_client_character_size_changed(GmWorldTextView *v,
guint width, guint height, GmMcpVmooClientView *view) {
gm_mcp_vmoo_client_view_update_metrics(view);
}
void
on_gm_mcp_vmoo_client_view_weak_notify(gpointer data, GObject *obj) {
GmMcpVmooClientView *view = (GmMcpVmooClientView *)(data);
g_signal_handlers_disconnect_by_func(view->view,
on_gm_mcp_vmoo_client_text_view_size_allocate, view);
g_signal_handlers_disconnect_by_func(view->view,
on_gm_mcp_vmoo_client_character_size_changed, view);
g_free(data);
}
void
gm_mcp_vmoo_client_create_view(GmMcpPackage *package, GObject *parent) {
GmMcpVmooClientView *client_view;
if (!GM_IS_WORLD_VIEW(parent)) {
return;
}
client_view = g_new0(GmMcpVmooClientView, 1);
client_view->package = GM_MCP_VMOO_CLIENT(package);
client_view->view = gm_world_view_text_view(GM_WORLD_VIEW(parent));
client_view->width = 0;
client_view->height = 0;
client_view->margin_width = gtk_text_view_get_left_margin(
GTK_TEXT_VIEW(client_view->view)) +
gtk_text_view_get_right_margin(
GTK_TEXT_VIEW(client_view->view));
client_view->margin_height = gtk_text_view_get_pixels_above_lines(
GTK_TEXT_VIEW(client_view->view)) +
gtk_text_view_get_pixels_below_lines(
GTK_TEXT_VIEW(client_view->view));
g_signal_connect(client_view->view, "size-allocate",
G_CALLBACK(on_gm_mcp_vmoo_client_text_view_size_allocate),
client_view);
g_signal_connect(client_view->view, "character_size_changed",
G_CALLBACK(on_gm_mcp_vmoo_client_character_size_changed),
client_view);
g_object_weak_ref(G_OBJECT(package),
on_gm_mcp_vmoo_client_view_weak_notify, client_view);
}

View File

@ -0,0 +1,58 @@
#ifndef __GM_MCP_VMOO_CLIENT_H__
#define __GM_MCP_VMOO_CLIENT_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_VMOO_CLIENT (gm_mcp_vmoo_client_get_type())
#define GM_MCP_VMOO_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_VMOO_CLIENT, GmMcpVmooClient))
#define GM_MCP_VMOO_CLIENT_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_VMOO_CLIENT, GmMcpVmooClient const))
#define GM_MCP_VMOO_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_VMOO_CLIENT, GmMcpVmooClientClass))
#define GM_IS_MCP_VMOO_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_VMOO_CLIENT))
#define GM_IS_MCP_VMOO_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_VMOO_CLIENT))
#define GM_MCP_VMOO_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_VMOO_CLIENT, GmMcpVmooClientClass))
/* Private structure type */
typedef struct _GmMcpVmooClientPrivate GmMcpVmooClientPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpVmooClient GmMcpVmooClient;
struct _GmMcpVmooClient {
GmMcpPackage parent;
/*< private > */
GmMcpVmooClientPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpVmooClientClass GmMcpVmooClientClass;
struct _GmMcpVmooClientClass {
GmMcpPackageClass parent_class;
/* Signals
void (* proto) (GmMcpVmooClient *obj); */
};
GType gm_mcp_vmoo_client_get_type(void) G_GNUC_CONST;
GmMcpVmooClient *gm_mcp_vmoo_client_new(void);
G_END_DECLS
#endif /* __GM_MCP_VMOO_CLIENT_H__ */

View File

@ -0,0 +1,623 @@
#include <strings.h>
#include <string.h>
#include "gm-mcp-vmoo-userlist.h"
#include "gm-mcp-userlist-view.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;
};
/* Signals */
enum {
PLAYER_ADDED,
PLAYER_REMOVED,
NAME_CHANGED,
STATE_CHANGED,
RANK_CHANGED,
NUM_SIGNALS
};
static guint gm_mcp_vmoo_userlist_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmMcpVmooUserlist, gm_mcp_vmoo_userlist, GM_TYPE_MCP_PACKAGE)
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);
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_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_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;
}
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));
}
}
}
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;
}
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) {
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);
} 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;
}
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);
}
}
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;
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;
}
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;
}
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);
g_free(sort);
} else {
GM_DEBUG("User %d does not exist!", nr->i);
}
} else {
GM_DEBUG("Nr is not an object: %d", nr->type);
}
}
}
void
gm_mcp_vmoo_userlist_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
MOOVar *you;
GmMcpVmooUserlist *userlist = GM_MCP_VMOO_USERLIST(package);
if (suffix && strcmp(suffix, "you") == 0) {
you = MOOVar_parse(gm_mcp_find_value(fields, "nr"));
if (you->type == OBJECT) {
userlist->priv->you = you->i;
MOOVar_free(you);
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleSimple: "
"you is not an object!");
}
}
}
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);
}

View File

@ -0,0 +1,66 @@
#ifndef __GM_MCP_VMOO_USERLIST_H__
#define __GM_MCP_VMOO_USERLIST_H__
#include <glib-object.h>
#include <gtk/gtk.h>
#include "gm-mcp-package.h"
G_BEGIN_DECLS
/*
* Type checking and casting macros
*/
#define GM_TYPE_MCP_VMOO_USERLIST (gm_mcp_vmoo_userlist_get_type())
#define GM_MCP_VMOO_USERLIST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
GM_TYPE_MCP_VMOO_USERLIST, GmMcpVmooUserlist))
#define GM_MCP_VMOO_USERLIST_CONST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),\
GM_TYPE_MCP_VMOO_USERLIST, GmMcpVmooUserlist const))
#define GM_MCP_VMOO_USERLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), \
GM_TYPE_MCP_VMOO_USERLIST, GmMcpVmooUserlistClass))
#define GM_IS_MCP_VMOO_USERLIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), \
GM_TYPE_MCP_VMOO_USERLIST))
#define GM_IS_MCP_VMOO_USERLIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \
GM_TYPE_MCP_VMOO_USERLIST))
#define GM_MCP_VMOO_USERLIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), \
GM_TYPE_MCP_VMOO_USERLIST, GmMcpVmooUserlistClass))
/* Private structure type */
typedef struct _GmMcpVmooUserlistPrivate GmMcpVmooUserlistPrivate;
/*
* Main object structure
*/
typedef struct _GmMcpVmooUserlist GmMcpVmooUserlist;
struct _GmMcpVmooUserlist {
GmMcpPackage parent;
/*< private > */
GmMcpVmooUserlistPrivate *priv;
};
/*
* Class definition
*/
typedef struct _GmMcpVmooUserlistClass GmMcpVmooUserlistClass;
struct _GmMcpVmooUserlistClass {
GmMcpPackageClass parent_class;
/* Signals */
void (* player_added) (GmMcpVmooUserlist *obj, gint id,
gchar const *name, gchar const *icon, gchar const *sort);
void (* player_removed) (GmMcpVmooUserlist *obj, gint id);
void (* name_changed) (GmMcpVmooUserlist *obj, gint id,
gchar const *name, gchar const *sort);
void (* state_changed) (GmMcpVmooUserlist *obj, gint id,
gchar const *icon, gchar const *sort);
void (* rank_changed) (GmMcpVmooUserlist *obj, gint id,
gchar const *icon, gchar const *sort);
};
GType gm_mcp_vmoo_userlist_get_type(void) G_GNUC_CONST;
GmMcpVmooUserlist *gm_mcp_vmoo_userlist_new(void);
G_END_DECLS
#endif /* __GM_MCP_VMOO_USERLIST_H__ */