Fixed utf8 issue, added reconnect, added properties, added notify_message signal
This commit is contained in:
parent
c06362a750
commit
52f0c5a54e
|
@ -40,6 +40,10 @@ struct _GmWorldPrivate {
|
|||
gboolean active;
|
||||
guint activity;
|
||||
gchar *buffer;
|
||||
gboolean manual_disconnect;
|
||||
time_t manual_disconnect_timeout;
|
||||
guint reconnect_id;
|
||||
time_t last_command;
|
||||
|
||||
GmOptions *options;
|
||||
GmTriggers *triggers;
|
||||
|
@ -53,6 +57,15 @@ struct _GmWorldPrivate {
|
|||
gint fd_log;
|
||||
};
|
||||
|
||||
/* Properties */
|
||||
enum {
|
||||
PROP_0,
|
||||
|
||||
PROP_NAME,
|
||||
PROP_ACTIVE,
|
||||
PROP_ACTIVITY
|
||||
};
|
||||
|
||||
/* Signals */
|
||||
|
||||
enum {
|
||||
|
@ -64,10 +77,8 @@ enum {
|
|||
TEXT_RECEIVED,
|
||||
EDITOR_ADDED,
|
||||
EDITOR_REMOVED,
|
||||
NAME_CHANGED,
|
||||
ACTIVE_CHANGED,
|
||||
ACTIVITY_CHANGED,
|
||||
HIGHLIGHT,
|
||||
NOTIFY_MESSAGE,
|
||||
NUM_SIGNALS
|
||||
};
|
||||
|
||||
|
@ -94,6 +105,10 @@ gm_world_finalize(GObject *object) {
|
|||
if (world->priv->fd_log > 0) {
|
||||
close(world->priv->fd_log);
|
||||
}
|
||||
|
||||
if (world->priv->reconnect_id) {
|
||||
g_source_remove(world->priv->reconnect_id);
|
||||
}
|
||||
|
||||
gm_g_list_free_simple(world->priv->history);
|
||||
|
||||
|
@ -111,12 +126,41 @@ gm_world_finalize(GObject *object) {
|
|||
G_OBJECT_CLASS(gm_world_parent_class)->finalize(object);
|
||||
}
|
||||
|
||||
static void
|
||||
gm_world_get_property(GObject *object, guint prop_id, GValue *value,
|
||||
GParamSpec *pspec) {
|
||||
GmWorld *world = GM_WORLD(object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_NAME:
|
||||
g_value_set_string(value, gm_world_name(world));
|
||||
break;
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean(value, world->priv->active);
|
||||
break;
|
||||
case PROP_ACTIVITY:
|
||||
g_value_set_int(value, world->priv->activity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gm_world_class_init(GmWorldClass *klass) {
|
||||
GObjectClass *object_class = G_OBJECT_CLASS(klass);
|
||||
|
||||
object_class->finalize = gm_world_finalize;
|
||||
|
||||
object_class->get_property = gm_world_get_property;
|
||||
|
||||
g_object_class_install_property(object_class, PROP_NAME,
|
||||
g_param_spec_string("name", "NAME", "The worlds name", NULL,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property(object_class, PROP_ACTIVE,
|
||||
g_param_spec_boolean("active", "ACTIVE", "If world is active",
|
||||
FALSE, G_PARAM_READABLE));
|
||||
g_object_class_install_property(object_class, PROP_ACTIVITY,
|
||||
g_param_spec_boolean("activity", "ACTIVITY", "Lines of activity",
|
||||
0, G_PARAM_READABLE));
|
||||
|
||||
world_signals[ACTIVATE_REQUEST] =
|
||||
g_signal_new("activate_request",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
|
@ -203,39 +247,6 @@ gm_world_class_init(GmWorldClass *klass) {
|
|||
1,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
world_signals[NAME_CHANGED] =
|
||||
g_signal_new("name_changed",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GmWorldClass, name_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
world_signals[ACTIVE_CHANGED] =
|
||||
g_signal_new("active_changed",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GmWorldClass, active_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOOLEAN,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_BOOLEAN);
|
||||
|
||||
world_signals[ACTIVITY_CHANGED] =
|
||||
g_signal_new("activity_changed",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GmWorldClass, activity_changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__INT,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_INT);
|
||||
|
||||
world_signals[HIGHLIGHT] =
|
||||
g_signal_new("highlight",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
|
@ -248,6 +259,17 @@ gm_world_class_init(GmWorldClass *klass) {
|
|||
G_TYPE_INT,
|
||||
G_TYPE_INT,
|
||||
G_TYPE_STRING);
|
||||
|
||||
world_signals[NOTIFY_MESSAGE] =
|
||||
g_signal_new("notify_message",
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET(GmWorldClass, notify_message),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__STRING,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
g_type_class_add_private(object_class, sizeof(GmWorldPrivate));
|
||||
}
|
||||
|
@ -308,7 +330,8 @@ gm_world_load_input_history(GmWorld *world) {
|
|||
filename = g_strconcat(world->priv->path, G_DIR_SEPARATOR_S, "history",
|
||||
NULL);
|
||||
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.LoadInputHistory: loading history (%s)!", filename);
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.LoadInputHistory: loading history "
|
||||
"(%s)!", filename);
|
||||
|
||||
if ((f = fopen(filename, "r")) != NULL) {
|
||||
str = g_string_new("");
|
||||
|
@ -316,7 +339,8 @@ gm_world_load_input_history(GmWorld *world) {
|
|||
while (fgets(line, 1024 - 1, f) != NULL) {
|
||||
g_string_append(str, line);
|
||||
if (line[strlen(line) - 1] == '\n') {
|
||||
if (line[1] != '\0') { // Empty lines, we don't need to process those
|
||||
if (line[1] != '\0') {
|
||||
// Empty lines, we don't need to process those
|
||||
world->priv->history = g_list_append(world->priv->history,
|
||||
g_strndup(str->str, strlen(str->str) - 1));
|
||||
}
|
||||
|
@ -380,6 +404,25 @@ gm_world_load_triggers(GmWorld *world) {
|
|||
g_free(path);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gm_world_reconnect(GmWorld *world) {
|
||||
world->priv->reconnect_id = 0;
|
||||
const gchar *host, *port;
|
||||
|
||||
host = gm_net_current_host(world->priv->net);
|
||||
port = gm_net_current_port(world->priv->net);
|
||||
|
||||
if (!host) {
|
||||
host = gm_options_get(world->priv->options, "host");
|
||||
}
|
||||
if (!port) {
|
||||
port = gm_options_get(world->priv->options, "port");
|
||||
}
|
||||
|
||||
gm_world_connect_to(world, host, port);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Public */
|
||||
GmWorld *
|
||||
gm_world_new(gchar *path) {
|
||||
|
@ -389,10 +432,12 @@ gm_world_new(gchar *path) {
|
|||
if (path != NULL) {
|
||||
options_path = g_strconcat(path, "/settings", NULL);
|
||||
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating new world for %s", path);
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating new world for %s",
|
||||
path);
|
||||
world->priv->path = g_strdup(path);
|
||||
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating default world settings for %s", path);
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.new: creating default world "
|
||||
"settings for %s", path);
|
||||
gm_options_load(world->priv->options, options_path);
|
||||
|
||||
if (strlen(gm_options_get(world->priv->options, "charset")) == 0) {
|
||||
|
@ -446,6 +491,11 @@ gm_world_unload(GmWorld *world) {
|
|||
gm_world_remove_editor(world,
|
||||
GM_EDITOR(world->priv->editors->data));
|
||||
}
|
||||
|
||||
if (world->priv->reconnect_id) {
|
||||
g_source_remove(world->priv->reconnect_id);
|
||||
world->priv->reconnect_id = 0;
|
||||
}
|
||||
|
||||
g_signal_emit(world, world_signals[UNLOAD], 0);
|
||||
}
|
||||
|
@ -507,34 +557,37 @@ gm_world_current_port(GmWorld *world) {
|
|||
}
|
||||
|
||||
void
|
||||
gm_world_connect(GmWorld *world) {
|
||||
/*if (strlen(gm_options_get(world->priv->options, "host")) == 0) {
|
||||
g_signal_emit(world, world_signals[WORLD_ERROR], 0,
|
||||
_("World has no host, please fill in a host first"));
|
||||
} else if (strlen(gm_options_get(world->priv->options, "port")) == 0) {
|
||||
g_signal_emit(world, world_signals[WORLD_ERROR], 0,
|
||||
_("World has no port, please fill in a port first"));
|
||||
} else {*/
|
||||
gm_net_connect(world->priv->net,
|
||||
gm_options_get(world->priv->options, "host"),
|
||||
gm_options_get(world->priv->options, "port"));
|
||||
//}
|
||||
}
|
||||
gm_world_connect_to(GmWorld *world, gchar const *host, gchar const *port) {
|
||||
if (world->priv->reconnect_id) {
|
||||
g_source_remove(world->priv->reconnect_id);
|
||||
}
|
||||
|
||||
void
|
||||
gm_world_connect_to(GmWorld *world, gchar *host, gchar *port) {
|
||||
gm_net_connect(world->priv->net, host, port);
|
||||
}
|
||||
|
||||
void
|
||||
gm_world_connect(GmWorld *world) {
|
||||
gm_world_connect_to(world,
|
||||
gm_options_get(world->priv->options, "host"),
|
||||
gm_options_get(world->priv->options, "port"));
|
||||
}
|
||||
|
||||
void
|
||||
gm_world_disconnect(GmWorld *world) {
|
||||
world->priv->manual_disconnect = TRUE;
|
||||
world->priv->manual_disconnect_timeout = time(0) + 5;
|
||||
gm_net_disconnect(world->priv->net);
|
||||
}
|
||||
|
||||
void
|
||||
gm_world_prepare_disconnect(GmWorld *world) {
|
||||
world->priv->manual_disconnect = TRUE;
|
||||
world->priv->manual_disconnect_timeout = time(0) + 5;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gm_world_log_allowed(GmLogType type) {
|
||||
GmOptions *options = gm_app_options(gm_app_instance());
|
||||
// TODO: this can be optimized
|
||||
|
||||
switch (type) {
|
||||
case LOG_IN:
|
||||
|
@ -755,7 +808,7 @@ gm_world_apply_trigger(GmWorld *world, GmTrigger *trigger, gchar const *text,
|
|||
break;
|
||||
case TAT_NOTIFY:
|
||||
tmp = gm_world_triggers_subst(data->data, text, matches);
|
||||
// TODO
|
||||
g_signal_emit(world, world_signals[NOTIFY_MESSAGE], 0, tmp);
|
||||
g_free(tmp);
|
||||
break;
|
||||
case TAT_RUN_SCRIPT:
|
||||
|
@ -810,16 +863,29 @@ gm_world_process_triggers(GmWorld *world, gchar *text) {
|
|||
}
|
||||
|
||||
void
|
||||
gm_world_process_line(GmWorld *world, gchar *line) {
|
||||
gchar *non_text_start = NULL;
|
||||
gm_world_process_line(GmWorld *world, gchar *line, gint len) {
|
||||
gchar *non_text_start = NULL, *from;
|
||||
GmEditingInfo *einfo = &(world->priv->editing_info);
|
||||
GmEditor *editor;
|
||||
gchar *no_ansi;
|
||||
gboolean has_ansi_start;
|
||||
|
||||
if (strncmp(line, "\x1B[0m", 4) == 0) {
|
||||
non_text_start = g_strdup(line + 4);
|
||||
has_ansi_start = TRUE;
|
||||
from = line + 4;
|
||||
|
||||
if (len != -1) {
|
||||
len = len - 4;
|
||||
}
|
||||
} else {
|
||||
non_text_start = g_strdup(line);
|
||||
has_ansi_start = FALSE;
|
||||
from = line;
|
||||
}
|
||||
|
||||
if (len == -1) {
|
||||
non_text_start = g_strdup(from);
|
||||
} else {
|
||||
non_text_start = g_strndup(from, len);
|
||||
}
|
||||
|
||||
if (einfo->is_editing) {
|
||||
|
@ -858,7 +924,7 @@ gm_world_process_line(GmWorld *world, gchar *line) {
|
|||
}
|
||||
|
||||
if (strncmp(non_text_start, "#$\"", 3) == 0) {
|
||||
if (strlen(non_text_start) != strlen(line)) {
|
||||
if (has_ansi_start) {
|
||||
g_signal_emit(world, world_signals[TEXT_RECEIVED], 0,
|
||||
"\x1B[0m");
|
||||
}
|
||||
|
@ -870,11 +936,17 @@ gm_world_process_line(GmWorld *world, gchar *line) {
|
|||
gm_world_log(world, LOG_IN, non_text_start + 3);
|
||||
no_ansi = gm_ansi_strip(g_strdup(non_text_start + 3));
|
||||
} else {
|
||||
g_signal_emit(world, world_signals[TEXT_RECEIVED], 0, line);
|
||||
if (has_ansi_start) {
|
||||
g_signal_emit(world, world_signals[TEXT_RECEIVED], 0,
|
||||
"\x1B[0m");
|
||||
}
|
||||
|
||||
g_signal_emit(world, world_signals[TEXT_RECEIVED], 0,
|
||||
non_text_start);
|
||||
g_signal_emit(world, world_signals[TEXT_RECEIVED], 0, "\n");
|
||||
|
||||
gm_world_log(world, LOG_IN, line);
|
||||
no_ansi = gm_ansi_strip(g_strdup(line));
|
||||
gm_world_log(world, LOG_IN, non_text_start);
|
||||
no_ansi = gm_ansi_strip(g_strdup(non_text_start));
|
||||
}
|
||||
|
||||
/* Process triggers */
|
||||
|
@ -903,8 +975,8 @@ gm_world_process_input(GmWorld *world, gchar *text) {
|
|||
argstr = g_strdup(space + 1);
|
||||
}
|
||||
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.ProcessInput: Trying script %s (%s)", script,
|
||||
argstr);
|
||||
gm_debug_msg(DEBUG_DEFAULT, "GmWorld.ProcessInput: Trying script "
|
||||
"%s (%s)", script, argstr);
|
||||
script_ran = gm_scripts_run(gm_app_scripts(gm_app_instance()),
|
||||
world, script, argstr);
|
||||
|
||||
|
@ -973,6 +1045,7 @@ gm_world_sendln_log(GmWorld *world, gchar *text, GmLogType logtype) {
|
|||
|
||||
void
|
||||
gm_world_sendln(GmWorld *world, gchar *text) {
|
||||
world->priv->last_command = time(0);
|
||||
gm_world_sendln_log(world, text, LOG_OUT);
|
||||
}
|
||||
|
||||
|
@ -980,7 +1053,7 @@ void
|
|||
gm_world_set_active(GmWorld *world, gboolean active) {
|
||||
world->priv->active = active;
|
||||
|
||||
g_signal_emit(world, world_signals[ACTIVE_CHANGED], 0, active);
|
||||
g_object_notify(G_OBJECT(world), "active");
|
||||
|
||||
if (active) {
|
||||
gm_world_set_activity(world, 0);
|
||||
|
@ -996,7 +1069,7 @@ void
|
|||
gm_world_set_activity(GmWorld *world, gint activity) {
|
||||
world->priv->activity = activity;
|
||||
|
||||
g_signal_emit(world, world_signals[ACTIVITY_CHANGED], 0, activity);
|
||||
g_object_notify(G_OBJECT(world), "activity");
|
||||
}
|
||||
|
||||
gint
|
||||
|
@ -1039,8 +1112,7 @@ gm_world_name_changed(GmWorld *world) {
|
|||
gm_triggers_save_as(world->priv->triggers, tmp_path);
|
||||
g_free(tmp_path);
|
||||
|
||||
g_signal_emit(world, world_signals[NAME_CHANGED], 0,
|
||||
gm_options_get(world->priv->options, "name"));
|
||||
g_object_notify(G_OBJECT(world), "name");
|
||||
}
|
||||
|
||||
GmMcpSession *
|
||||
|
@ -1085,16 +1157,45 @@ on_gm_world_editor_save(GmEditor *editor, GmWorld *world) {
|
|||
|
||||
void
|
||||
on_gm_world_net_state_changing(GmNet *net, GmNetState state, GmWorld *world) {
|
||||
GmNetState prev_state = gm_net_state(net);
|
||||
|
||||
g_signal_emit(world, world_signals[STATE_CHANGING], 0, state);
|
||||
|
||||
if (state == GM_NET_STATE_DISCONNECTED) {
|
||||
if ((prev_state == GM_NET_STATE_CONNECTED ||
|
||||
prev_state == GM_NET_STATE_DISCONNECTING) &&
|
||||
state == GM_NET_STATE_DISCONNECTED) {
|
||||
gm_mcp_session_reset(world->priv->mcp);
|
||||
|
||||
#ifdef HAVE_RUBY
|
||||
gm_scripts_run(gm_app_scripts(gm_app_instance()), world,
|
||||
"on_disconnect", NULL);
|
||||
#endif
|
||||
|
||||
if (!world->priv->reconnect_id &&
|
||||
gm_options_get_int(world->priv->options, "reconnect")) {
|
||||
|
||||
// Manual disconnect timeout check
|
||||
if (world->priv->manual_disconnect ||
|
||||
time(0) < world->priv->manual_disconnect_timeout) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Last command send check
|
||||
if (difftime(time(0), world->priv->last_command) <= 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
world->priv->reconnect_id = g_timeout_add(3000,
|
||||
(GSourceFunc)gm_world_reconnect, world);
|
||||
gm_world_writeln(world, _("# Reconnecting in 3 seconds..."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
on_gm_world_net_state_changed(GmNet *net, GmNetState state, GmWorld *world) {
|
||||
if (state == GM_NET_STATE_CONNECTED) {
|
||||
world->priv->manual_disconnect = FALSE;
|
||||
gm_world_auto_login(world);
|
||||
|
||||
#ifdef HAVE_RUBY
|
||||
|
@ -1102,13 +1203,6 @@ on_gm_world_net_state_changed(GmNet *net, GmNetState state, GmWorld *world) {
|
|||
NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (state == GM_NET_STATE_DISCONNECTED) {
|
||||
#ifdef HAVE_RUBY
|
||||
gm_scripts_run(gm_app_scripts(gm_app_instance()), world,
|
||||
"on_disconnect", NULL);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1120,8 +1214,8 @@ on_gm_world_net_net_error(GmNet *net, gchar *error, gint code,
|
|||
void
|
||||
on_gm_world_net_bytes_recv(GmNet *net, gchar *text, gint len,
|
||||
GmWorld *world) {
|
||||
gchar *all, *utext, *ptr, *line, *p;
|
||||
gint i;
|
||||
gchar *all, *utext, *ptr, *start;
|
||||
gunichar ch, prev;
|
||||
|
||||
utext = gm_to_utf8_with_fallback(text, len,
|
||||
gm_options_get(world->priv->options, "charset"), "?");
|
||||
|
@ -1140,28 +1234,29 @@ on_gm_world_net_bytes_recv(GmNet *net, gchar *text, gint len,
|
|||
all = utext;
|
||||
}
|
||||
|
||||
// TODO: UTF-8 compliant
|
||||
line = (gchar *)(malloc((strlen(all) * sizeof(gchar)) + 1));
|
||||
i = 0;
|
||||
p = all;
|
||||
|
||||
ptr = start = all;
|
||||
prev = 0;
|
||||
|
||||
/* Find lines in `all' and process them */
|
||||
for (ptr = all; *ptr != '\0'; ptr++) {
|
||||
if (*ptr == '\n') {
|
||||
line[i] = '\0';
|
||||
line[i + 1] = '\0';
|
||||
while ((ch = g_utf8_get_char(ptr)) != '\0') {
|
||||
if (ch == '\n') {
|
||||
gm_world_process_line(world, start, ptr - start -
|
||||
(prev == '\r' ? 1 : 0));
|
||||
ptr = start = g_utf8_next_char(ptr);
|
||||
|
||||
gm_world_process_line(world, line);
|
||||
p = ptr + 1;
|
||||
i = 0;
|
||||
} else if (*ptr != '\r') {
|
||||
line[i] = *ptr;
|
||||
i++;
|
||||
// Skip \r
|
||||
if (g_utf8_get_char(ptr) == '\r') {
|
||||
ptr = start = g_utf8_next_char(ptr);
|
||||
}
|
||||
} else {
|
||||
ptr = g_utf8_next_char(ptr);
|
||||
}
|
||||
|
||||
prev = ch;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
world->priv->buffer = g_strdup(p);
|
||||
if (*start != '\0') {
|
||||
world->priv->buffer = g_strdup(start);
|
||||
}
|
||||
|
||||
g_free(all);
|
||||
|
|
|
@ -90,11 +90,9 @@ struct _GmWorldClass {
|
|||
void (* text_received) (GmWorld *world, gchar const *text);
|
||||
void (* editor_added) (GmWorld *world, GObject *editor);
|
||||
void (* editor_removed) (GmWorld *world, GObject *editor);
|
||||
void (* name_changed) (GmWorld *world, gchar const *name);
|
||||
void (* active_changed) (GmWorld *world, gboolean active);
|
||||
void (* activity_changed) (GmWorld *world, gint activity);
|
||||
void (* highlight) (GmWorld *world, gint start, gint end,
|
||||
gchar const *color);
|
||||
void (* notify_message) (GmWorld *world, gchar const *message);
|
||||
};
|
||||
|
||||
GType gm_world_get_type(void) G_GNUC_CONST;
|
||||
|
@ -127,8 +125,9 @@ gboolean gm_world_connected(GmWorld *world);
|
|||
gboolean gm_world_disconnected(GmWorld *world);
|
||||
|
||||
void gm_world_connect(GmWorld *world);
|
||||
void gm_world_connect_to(GmWorld *world, gchar *host, gchar *port);
|
||||
void gm_world_connect_to(GmWorld *world, gchar const *host, gchar const *port);
|
||||
void gm_world_disconnect(GmWorld *world);
|
||||
void gm_world_prepare_disconnect(GmWorld *world);
|
||||
void gm_world_add_editor(GmWorld *world, GmEditor *editor);
|
||||
void gm_world_remove_editor(GmWorld *world, GmEditor *editor);
|
||||
void gm_world_sendln_log(GmWorld *world, gchar *text, GmLogType logtype);
|
||||
|
|
Reference in New Issue