From 01e804f06e00c36c5680ebde07cbe17e6b256dc4 Mon Sep 17 00:00:00 2001 From: fatbob313 Date: Sun, 24 Jan 2010 16:15:28 +0000 Subject: [PATCH] Add option 'noenter' to channel configuration and implement support. Fix a couple of error cases regarding temp channel creation/deletion. --- src/channel.c | 21 +++++++++++++++++++++ src/channel.h | 3 ++- src/conf.c | 18 +++++++++++++----- src/conf.h | 1 + src/messagehandler.c | 24 +++++++++++++++++++++--- 5 files changed, 58 insertions(+), 9 deletions(-) diff --git a/src/channel.c b/src/channel.c index 942c348..d55653b 100644 --- a/src/channel.c +++ b/src/channel.c @@ -149,6 +149,7 @@ void Chan_init() } if (i == 0) { rootChan = createChannel(0, chdesc.name, chdesc.description); + rootChan->noenter = chdesc.noenter; list_add_tail(&rootChan->flatlist_node, &channels); if (strcmp(defaultChannelName, chdesc.name) == 0) defaultChan = rootChan; @@ -156,6 +157,7 @@ void Chan_init() else { channel_t *ch, *ch_itr = NULL; ch = Chan_createChannel(chdesc.name, chdesc.description); + ch->noenter = chdesc.noenter; if (strcmp(defaultChannelName, chdesc.name) == 0) { Log_info("Setting default channel %s", ch->name); @@ -176,6 +178,9 @@ void Chan_init() } if (defaultChan == NULL) defaultChan = rootChan; + + if (defaultChan->noenter) + Log_fatal("Error in channel configuration: default channel is marked as noenter"); /* Channel links */ for (i = 0; ; i++) { @@ -276,6 +281,22 @@ int Chan_playerJoin_id(int channelid, client_t *client) return Chan_playerJoin(ch_itr, client); } +bool_t Chan_playerJoin_id_test(int channelid) +{ + channel_t *ch_itr = NULL; + do { + Chan_iterate(&ch_itr); + } while (ch_itr != NULL && ch_itr->id != channelid); + if (ch_itr == NULL) { + Log_warn("Channel id %d not found - ignoring.", channelid); + return false; + } + if (ch_itr->noenter) + return false; + else + return true; +} + #if 0 void Chan_addChannel_id(int parentId, channel_t *ch) { diff --git a/src/channel.h b/src/channel.h index a7f31d5..aeb21dc 100644 --- a/src/channel.h +++ b/src/channel.h @@ -40,7 +40,7 @@ typedef struct channel { char name[MAX_TEXT]; char desc[MAX_TEXT]; struct channel *parent; - bool_t temporary; + bool_t temporary, noenter; struct dlist node; struct dlist subs; struct dlist clients; @@ -57,6 +57,7 @@ void Chan_addClient(channel_t *c, client_t *client); void Chan_removeClient(channel_t *c, client_t *client); int Chan_playerJoin(channel_t *ch, client_t *client); int Chan_playerJoin_id(int channelid, client_t *client); +bool_t Chan_playerJoin_id_test(int channelid); channel_t *Chan_iterate(channel_t **channelpptr); channel_t *Chan_iterate_siblings(channel_t *parent, channel_t **channelpptr); channel_t *Chan_createChannel(const char *name, const char *desc); diff --git a/src/conf.c b/src/conf.c index ae91b6e..a9d2c08 100644 --- a/src/conf.c +++ b/src/conf.c @@ -195,20 +195,28 @@ int Conf_getNextChannel(conf_channel_t *chdesc, int index) sprintf(configstr, "channels.[%d].name", index); setting = config_lookup(&configuration, configstr); if (setting == NULL) - return -1; + return -1; /* Required */ strncpy(chdesc->name, config_setting_get_string(setting), MAX_TEXT); sprintf(configstr, "channels.[%d].parent", index); setting = config_lookup(&configuration, configstr); if (setting == NULL) - return -1; + return -1; /* Required */ strncpy(chdesc->parent, config_setting_get_string(setting), MAX_TEXT); sprintf(configstr, "channels.[%d].description", index); setting = config_lookup(&configuration, configstr); - if (setting == NULL) - return -1; - strncpy(chdesc->description, config_setting_get_string(setting), MAX_TEXT); + if (setting == NULL) /* Optional */ + strncpy(chdesc->description, "", MAX_TEXT); + else + strncpy(chdesc->description, config_setting_get_string(setting), MAX_TEXT); + + sprintf(configstr, "channels.[%d].noenter", index); + setting = config_lookup(&configuration, configstr); + if (setting == NULL) /* Optional */ + chdesc->noenter = false; + else + chdesc->noenter = config_setting_get_bool(setting); return 0; } diff --git a/src/conf.h b/src/conf.h index c0a0825..04beaa3 100644 --- a/src/conf.h +++ b/src/conf.h @@ -49,6 +49,7 @@ typedef struct { char parent[MAX_TEXT]; char name[MAX_TEXT]; char description[MAX_TEXT]; + bool_t noenter; } conf_channel_t; typedef struct { diff --git a/src/messagehandler.c b/src/messagehandler.c index ebd602f..c69f65e 100644 --- a/src/messagehandler.c +++ b/src/messagehandler.c @@ -326,9 +326,10 @@ void Mh_handle_message(client_t *client, message_t *msg) } if (msg->payload.userState->has_channel_id) { int leave_id; + if (!Chan_playerJoin_id_test(msg->payload.userState->channel_id)) + break; leave_id = Chan_playerJoin_id(msg->payload.userState->channel_id, client); if (leave_id > 0) { - /* XXX - need to send update to remove channel if temporary */ Log_debug("Removing channel ID %d", leave_id); sendmsg = Msg_create(ChannelRemove); sendmsg->payload.channelRemove->channel_id = leave_id; @@ -354,6 +355,7 @@ void Mh_handle_message(client_t *client, message_t *msg) if (sendmsg != NULL) Client_send_message_except(NULL, sendmsg); break; + case TextMessage: msg->payload.textMessage->has_actor = true; msg->payload.textMessage->actor = client->sessionId; @@ -464,7 +466,7 @@ void Mh_handle_message(client_t *client, message_t *msg) case ChannelState: { channel_t *ch_itr, *parent, *newchan; - + int leave_id; /* Don't allow any changes to existing channels */ if (msg->payload.channelState->has_channel_id) { sendPermissionDenied(client, "Not supported by uMurmur"); @@ -501,6 +503,15 @@ void Mh_handle_message(client_t *client, message_t *msg) break; } } + if (ch_itr != NULL) + break; + + /* Disallow temporary channels as siblings to temporary channels */ + if (parent->temporary) { + sendPermissionDenied(client, "Parent channel is temporary channel"); + break; + } + /* XXX - Murmur looks for "\\w" and sends perm denied if not found. * I don't know why so I don't do that here... */ @@ -522,7 +533,14 @@ void Mh_handle_message(client_t *client, message_t *msg) sendmsg->payload.userState->has_channel_id = true; sendmsg->payload.userState->channel_id = newchan->id; Client_send_message_except(NULL, sendmsg); - Chan_playerJoin(newchan, client); + + leave_id = Chan_playerJoin(newchan, client); + if (leave_id > 0) { + Log_debug("Removing channel ID %d", leave_id); + sendmsg = Msg_create(ChannelRemove); + sendmsg->payload.channelRemove->channel_id = leave_id; + Client_send_message_except(NULL, sendmsg); + } } break; -- 2.30.2