From fc50b63d454f59620e0d3ef6674bd9ae54a6175f Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 22 Jan 2015 00:28:24 +0100 Subject: Moved the Hercules Channel System to its own file/interface Signed-off-by: Haru --- src/map/atcommand.c | 219 ++++++++++++++++++++++++++-------------------------- 1 file changed, 110 insertions(+), 109 deletions(-) (limited to 'src/map/atcommand.c') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d75282746..60f0fc8ed 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -14,6 +14,7 @@ #include "HPMmap.h" #include "battle.h" +#include "channel.h" #include "chat.h" #include "chrif.h" #include "clif.h" @@ -5461,7 +5462,7 @@ ACMD(autotrade) ((timeout > 0) ? min(timeout,battle_config.at_timeout) : battle_config.at_timeout) * 60000, SCFLAG_NONE); } - clif->chsys_quit(sd); + channel->quit(sd); clif->authfail_fd(sd->fd, 15); @@ -8612,43 +8613,43 @@ ACMD(cart) { } /* [Ind/Hercules] */ ACMD(join) { - struct hChSysCh *channel = NULL; - char name[HCHSYS_NAME_LENGTH], pass[HCHSYS_NAME_LENGTH]; + struct channel_data *chan = NULL; + char name[HCS_NAME_LENGTH], pass[HCS_NAME_LENGTH]; if (!message || !*message || sscanf(message, "%19s %19s", name, pass) < 1) { sprintf(atcmd_output, msg_txt(1399),command); // Unknown Channel (usage: %s <#channel_name>) clif->message(fd, atcmd_output); return false; } - if (clif->hChSys->local && strcmpi(name + 1, clif->hChSys->local_name) == 0) { + if (channel->config->local && strcmpi(name + 1, channel->config->local_name) == 0) { if( !map->list[sd->bl.m].channel ) { - clif->chsys_mjoin(sd); + channel->map_join(sd); if( map->list[sd->bl.m].channel ) /* join might have refused, map has chatting capabilities disabled */ return true; } else - channel = map->list[sd->bl.m].channel; - } else if (clif->hChSys->ally && sd->status.guild_id && strcmpi(name + 1, clif->hChSys->ally_name) == 0) { + chan = map->list[sd->bl.m].channel; + } else if (channel->config->ally && sd->status.guild_id && strcmpi(name + 1, channel->config->ally_name) == 0) { struct guild *g = sd->guild; if( !g ) return false;/* unlikely, but we wont let it crash anyway. */ - channel = g->channel; - } else if( !( channel = strdb_get(clif->channel_db, name + 1) ) ) { + chan = g->channel; + } else if( !( chan = strdb_get(channel->db, name + 1) ) ) { sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) clif->message(fd, atcmd_output); return false; } - if( !channel ) { + if( !chan ) { sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) clif->message(fd, atcmd_output); return false; } - if( idb_exists(channel->users, sd->status.char_id) ) { + if( idb_exists(chan->users, sd->status.char_id) ) { sprintf(atcmd_output, msg_txt(1436),name); // You're already in the '%s' channel clif->message(fd, atcmd_output); return false; } - if( channel->pass[0] != '\0' && strcmp(channel->pass,pass) != 0 ) { + if( chan->pass[0] != '\0' && strcmp(chan->pass,pass) != 0 ) { if( pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sd->stealth = true; } else { @@ -8658,29 +8659,29 @@ ACMD(join) { } } - if( channel->banned && idb_exists(channel->banned, sd->status.account_id) ) { + if( chan->banned && idb_exists(chan->banned, sd->status.account_id) ) { sprintf(atcmd_output, msg_txt(1438),name); // You cannot join the '%s' channel because you've been banned from it clif->message(fd, atcmd_output); return false; } - if (!(channel->opt & hChSys_OPT_ANNOUNCE_JOIN)) { + if (!(chan->opt & HCS_OPT_ANNOUNCE_JOIN)) { sprintf(atcmd_output, msg_txt(1403),name); // You're now in the '%s' channel clif->message(fd, atcmd_output); } - if( channel->type == hChSys_ALLY ) { + if( chan->type == HCS_TYPE_ALLY ) { struct guild *g = sd->guild; int i; for (i = 0; i < MAX_GUILDALLIANCE; i++) { struct guild *sg = NULL; if( g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id) ) ) { if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) { - clif->chsys_join(sg->channel,sd); + channel->join(sg->channel,sd); } } } } - clif->chsys_join(channel,sd); + channel->join(chan,sd); return true; } @@ -8736,81 +8737,81 @@ static inline void atcmd_channel_help(int fd, const char *command, bool can_crea } /* [Ind/Hercules] */ ACMD(channel) { - struct hChSysCh *channel; - char subcmd[HCHSYS_NAME_LENGTH], sub1[HCHSYS_NAME_LENGTH], sub2[HCHSYS_NAME_LENGTH], sub3[HCHSYS_NAME_LENGTH]; + struct channel_data *chan; + char subcmd[HCS_NAME_LENGTH], sub1[HCS_NAME_LENGTH], sub2[HCS_NAME_LENGTH], sub3[HCS_NAME_LENGTH]; unsigned char k = 0; sub1[0] = sub2[0] = sub3[0] = '\0'; if (!message || !*message || sscanf(message, "%19s %19s %19s %19s", subcmd, sub1, sub2, sub3) < 1) { - atcmd_channel_help(fd,command, (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))); + atcmd_channel_help(fd,command, (channel->config->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))); return true; } - if (strcmpi(subcmd,"create") == 0 && (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))) { + if (strcmpi(subcmd,"create") == 0 && (channel->config->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))) { // sub1 = channel name; sub2 = password; sub3 = unused size_t len = strlen(sub1); if (sub1[0] != '#') { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; - } else if (len < 3 || len > HCHSYS_NAME_LENGTH) { - sprintf(atcmd_output, msg_txt(1406), HCHSYS_NAME_LENGTH);// Channel length must be between 3 and %d + } else if (len < 3 || len > HCS_NAME_LENGTH) { + sprintf(atcmd_output, msg_txt(1406), HCS_NAME_LENGTH);// Channel length must be between 3 and %d clif->message(fd, atcmd_output); return false; } else if (sub3[0] != '\0') { clif->message(fd, msg_txt(1408)); // Channel password may not contain spaces return false; } - if (strcmpi(sub1 + 1, clif->hChSys->local_name) == 0 || strcmpi(sub1 + 1, clif->hChSys->ally_name) == 0 || strdb_exists(clif->channel_db, sub1 + 1)) { + if (strcmpi(sub1 + 1, channel->config->local_name) == 0 || strcmpi(sub1 + 1, channel->config->ally_name) == 0 || strdb_exists(channel->db, sub1 + 1)) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - CREATE( channel, struct hChSysCh, 1 ); - clif->chsys_create(channel,sub1 + 1,sub2,0); + CREATE(chan, struct channel_data, 1); + channel->create(chan,sub1 + 1,sub2,0); - channel->owner = sd->status.char_id; - channel->type = hChSys_PRIVATE; + chan->owner = sd->status.char_id; + chan->type = HCS_TYPE_PRIVATE; - if( !( channel->opt & hChSys_OPT_ANNOUNCE_JOIN ) ) { + if( !( chan->opt & HCS_OPT_ANNOUNCE_JOIN ) ) { sprintf(atcmd_output, msg_txt(1403),sub1); // You're now in the '%s' channel clif->message(fd, atcmd_output); } - clif->chsys_join(channel,sd); + channel->join(chan,sd); } else if (strcmpi(subcmd,"list") == 0) { // sub1 = list type; sub2 = unused; sub3 = unused if (sub1[0] != '\0' && strcmpi(sub1,"colors") == 0) { char mout[40]; - for (k = 0; k < clif->hChSys->colors_count; k++) { + for (k = 0; k < channel->config->colors_count; k++) { unsigned short msg_len = 1; - msg_len += sprintf(mout, "[ %s list colors ] : %s", command, clif->hChSys->colors_name[k]); + msg_len += sprintf(mout, "[ %s list colors ] : %s", command, channel->config->colors_name[k]); WFIFOHEAD(fd,msg_len + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = msg_len + 12; WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = clif->hChSys->colors[k]; + WFIFOL(fd,8) = channel->config->colors[k]; safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); WFIFOSET(fd, msg_len + 12); } } else { - DBIterator *iter = db_iterator(clif->channel_db); + DBIterator *iter = db_iterator(channel->db); bool show_all = pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ? true : false; clif->message(fd, msg_txt(1410)); // -- Public Channels - if (clif->hChSys->local) { - sprintf(atcmd_output, msg_txt(1409), clif->hChSys->local_name, map->list[sd->bl.m].channel ? db_size(map->list[sd->bl.m].channel->users) : 0);// - #%s ( %d users ) + if (channel->config->local) { + sprintf(atcmd_output, msg_txt(1409), channel->config->local_name, map->list[sd->bl.m].channel ? db_size(map->list[sd->bl.m].channel->users) : 0);// - #%s ( %d users ) clif->message(fd, atcmd_output); } - if (clif->hChSys->ally && sd->status.guild_id) { + if (channel->config->ally && sd->status.guild_id) { struct guild *g = sd->guild; if( !g ) { dbi_destroy(iter); return false; } - sprintf(atcmd_output, msg_txt(1409), clif->hChSys->ally_name, db_size(g->channel->users));// - #%s ( %d users ) + sprintf(atcmd_output, msg_txt(1409), channel->config->ally_name, db_size(g->channel->users));// - #%s ( %d users ) clif->message(fd, atcmd_output); } - for (channel = dbi_first(iter); dbi_exists(iter); channel = dbi_next(iter)) { - if (show_all || channel->type == hChSys_PUBLIC || channel->type == hChSys_IRC) { - sprintf(atcmd_output, msg_txt(1409), channel->name, db_size(channel->users));// - #%s ( %d users ) + for (chan = dbi_first(iter); dbi_exists(iter); chan = dbi_next(iter)) { + if (show_all || chan->type == HCS_TYPE_PUBLIC || chan->type == HCS_TYPE_IRC) { + sprintf(atcmd_output, msg_txt(1409), chan->name, db_size(chan->users));// - #%s ( %d users ) clif->message(fd, atcmd_output); } } @@ -8823,29 +8824,29 @@ ACMD(channel) { return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - for (k = 0; k < clif->hChSys->colors_count; k++) { - if (strcmpi(sub2, clif->hChSys->colors_name[k]) == 0) + for (k = 0; k < channel->config->colors_count; k++) { + if (strcmpi(sub2, channel->config->colors_name[k]) == 0) break; } - if (k == clif->hChSys->colors_count) { + if (k == channel->config->colors_count) { sprintf(atcmd_output, msg_txt(1411), sub2);// Unknown color '%s' clif->message(fd, atcmd_output); return false; } - channel->color = k; - sprintf(atcmd_output, msg_txt(1413), sub1, clif->hChSys->colors_name[k]);// '%s' channel color updated to '%s' + chan->color = k; + sprintf(atcmd_output, msg_txt(1413), sub1, channel->config->colors_name[k]);// '%s' channel color updated to '%s' clif->message(fd, atcmd_output); } else if (strcmpi(subcmd,"leave") == 0) { // sub1 = channel name; sub2 = unused; sub3 = unused @@ -8862,17 +8863,17 @@ ACMD(channel) { clif->message(fd, atcmd_output); return false; } - if (sd->channels[k]->type == hChSys_ALLY) { + if (sd->channels[k]->type == HCS_TYPE_ALLY) { do { for (k = 0; k < sd->channel_count; k++) { - if (sd->channels[k]->type == hChSys_ALLY) { - clif->chsys_left(sd->channels[k],sd); + if (sd->channels[k]->type == HCS_TYPE_ALLY) { + channel->leave(sd->channels[k],sd); break; } } } while (k != sd->channel_count); } else { - clif->chsys_left(sd->channels[k],sd); + channel->leave(sd->channels[k],sd); } sprintf(atcmd_output, msg_txt(1426),sub1); // You've left the '%s' channel clif->message(fd, atcmd_output); @@ -8910,7 +8911,7 @@ ACMD(channel) { } else if (strcmpi(subcmd,"ban") == 0) { // sub1 = channel name; sub2 = unused; sub3 = unused struct map_session_data *pl_sd = NULL; - struct hChSysBanEntry *entry = NULL; + struct channel_ban_entry *entry = NULL; char sub4[NAME_LENGTH]; ///< player name if (sub1[0] != '#') { @@ -8918,13 +8919,13 @@ ACMD(channel) { return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -8947,20 +8948,20 @@ ACMD(channel) { return false; } - if (channel->banned && idb_exists(channel->banned,pl_sd->status.account_id)) { + if (chan->banned && idb_exists(chan->banned,pl_sd->status.account_id)) { sprintf(atcmd_output, msg_txt(1465), pl_sd->status.name);// Player '%s' is already banned from this channel clif->message(fd, atcmd_output); return false; } - if (!channel->banned) - channel->banned = idb_alloc(DB_OPT_BASE|DB_OPT_ALLOW_NULL_DATA|DB_OPT_RELEASE_DATA); + if (!chan->banned) + chan->banned = idb_alloc(DB_OPT_BASE|DB_OPT_ALLOW_NULL_DATA|DB_OPT_RELEASE_DATA); - CREATE(entry, struct hChSysBanEntry, 1); + CREATE(entry, struct channel_ban_entry, 1); safestrncpy(entry->name, pl_sd->status.name, NAME_LENGTH); - idb_put(channel->banned, pl_sd->status.account_id, entry); + idb_put(chan->banned, pl_sd->status.account_id, entry); - clif->chsys_left(channel,pl_sd); + channel->leave(chan,pl_sd); sprintf(atcmd_output, msg_txt(1437),pl_sd->status.name,sub1); // Player '%s' has now been banned from '%s' channel clif->message(fd, atcmd_output); @@ -8973,17 +8974,17 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!channel->banned) { + if (!chan->banned) { sprintf(atcmd_output, msg_txt(1439), sub1);// Channel '%s' has no banned players clif->message(fd, atcmd_output); return false; @@ -8999,16 +9000,16 @@ ACMD(channel) { clif->message(fd, atcmd_output); return false; } - if (!idb_exists(channel->banned,pl_sd->status.account_id)) { + if (!idb_exists(chan->banned,pl_sd->status.account_id)) { sprintf(atcmd_output, msg_txt(1440), pl_sd->status.name);// Player '%s' is not banned from this channel clif->message(fd, atcmd_output); return false; } - idb_remove(channel->banned, pl_sd->status.account_id); - if (!db_size(channel->banned)) { - db_destroy(channel->banned); - channel->banned = NULL; + idb_remove(chan->banned, pl_sd->status.account_id); + if (!db_size(chan->banned)) { + db_destroy(chan->banned); + chan->banned = NULL; } sprintf(atcmd_output, msg_txt(1441),pl_sd->status.name,sub1); // Player '%s' has now been unbanned from the '%s' channel @@ -9019,23 +9020,23 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!channel->banned) { + if (!chan->banned) { sprintf(atcmd_output, msg_txt(1439), sub1);// Channel '%s' has no banned players clif->message(fd, atcmd_output); return false; } - db_destroy(channel->banned); - channel->banned = NULL; + db_destroy(chan->banned); + chan->banned = NULL; sprintf(atcmd_output, msg_txt(1442),sub1); // Removed all bans from '%s' channel clif->message(fd, atcmd_output); @@ -9049,27 +9050,27 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !isA) { + if (chan->owner != sd->status.char_id && !isA) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!channel->banned) { + if (!chan->banned) { sprintf(atcmd_output, msg_txt(1439), sub1);// Channel '%s' has no banned players clif->message(fd, atcmd_output); return false; } - sprintf(atcmd_output, msg_txt(1443), channel->name);// -- '%s' ban list + sprintf(atcmd_output, msg_txt(1443), chan->name);// -- '%s' ban list clif->message(fd, atcmd_output); - iter = db_iterator(channel->banned); + iter = db_iterator(chan->banned); for (data = iter->first(iter,&key); iter->exists(iter); data = iter->next(iter,&key)) { - struct hChSysBanEntry * entry = DB->data2ptr(data); + struct channel_ban_entry *entry = DB->data2ptr(data); if (!isA) sprintf(atcmd_output, msg_txt(1444), entry->name);// - %s %s @@ -9090,12 +9091,12 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(channel = strdb_get(clif->channel_db, sub1 + 1))) { + if (!(chan = strdb_get(channel->db, sub1 + 1))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; } - if (channel->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; @@ -9119,60 +9120,60 @@ ACMD(channel) { return false; } if (sub3[0] == '\0') { - if (k == hChSys_OPT_MSG_DELAY) { + if (k == HCS_OPT_MSG_DELAY) { sprintf(atcmd_output, msg_txt(1466), opt_str[k]);// For '%s' you need the amount of seconds (from 0 to 10) clif->message(fd, atcmd_output); return false; - } else if (channel->opt & k) { + } else if (chan->opt & k) { sprintf(atcmd_output, msg_txt(1449), opt_str[k],opt_str[k]); // option '%s' is already enabled, if you'd like to disable it type '@channel setopt %s 0' clif->message(fd, atcmd_output); return false; } else { - channel->opt |= k; - sprintf(atcmd_output, msg_txt(1450), opt_str[k],channel->name);//option '%s' is now enabled for channel '%s' + chan->opt |= k; + sprintf(atcmd_output, msg_txt(1450), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s' clif->message(fd, atcmd_output); return true; } } else { int v = atoi(sub3); - if (k == hChSys_OPT_MSG_DELAY) { + if (k == HCS_OPT_MSG_DELAY) { if (v < 0 || v > 10) { sprintf(atcmd_output, msg_txt(1451), v, opt_str[k]);// value '%d' for option '%s' is out of range (limit is 0-10) clif->message(fd, atcmd_output); return false; } if (v == 0) { - channel->opt &=~ k; - channel->msg_delay = 0; - sprintf(atcmd_output, msg_txt(1453), opt_str[k],channel->name,v);// option '%s' is now disabled for channel '%s' + chan->opt &=~ k; + chan->msg_delay = 0; + sprintf(atcmd_output, msg_txt(1453), opt_str[k],chan->name,v);// option '%s' is now disabled for channel '%s' clif->message(fd, atcmd_output); return true; } else { - channel->opt |= k; - channel->msg_delay = v; - sprintf(atcmd_output, msg_txt(1452), opt_str[k],channel->name,v);// option '%s' is now enabled for channel '%s' with %d seconds + chan->opt |= k; + chan->msg_delay = v; + sprintf(atcmd_output, msg_txt(1452), opt_str[k],chan->name,v);// option '%s' is now enabled for channel '%s' with %d seconds clif->message(fd, atcmd_output); return true; } } else { if (v) { - if (channel->opt & k) { + if (chan->opt & k) { sprintf(atcmd_output, msg_txt(1449), opt_str[k],opt_str[k]); // option '%s' is already enabled, if you'd like to disable it type '@channel opt %s 0' clif->message(fd, atcmd_output); return false; } else { - channel->opt |= k; - sprintf(atcmd_output, msg_txt(1454), opt_str[k],channel->name);//option '%s' is now enabled for channel '%s' + chan->opt |= k; + sprintf(atcmd_output, msg_txt(1454), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s' clif->message(fd, atcmd_output); } } else { - if (!(channel->opt & k)) { - sprintf(atcmd_output, msg_txt(1454), opt_str[k],channel->name); // option '%s' is not enabled on channel '%s' + if (!(chan->opt & k)) { + sprintf(atcmd_output, msg_txt(1454), opt_str[k],chan->name); // option '%s' is not enabled on channel '%s' clif->message(fd, atcmd_output); return false; } else { - channel->opt &=~ k; - sprintf(atcmd_output, msg_txt(1453), opt_str[k],channel->name);// option '%s' is now disabled for channel '%s' + chan->opt &=~ k; + sprintf(atcmd_output, msg_txt(1453), opt_str[k],chan->name);// option '%s' is now disabled for channel '%s' clif->message(fd, atcmd_output); return true; } @@ -9180,7 +9181,7 @@ ACMD(channel) { } } } else { - atcmd_channel_help(fd, command, (clif->hChSys->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))); + atcmd_channel_help(fd, command, (channel->config->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))); } return true; } @@ -9191,14 +9192,14 @@ ACMD(fontcolor) { char mout[40]; if( !message || !*message ) { - for( k = 0; k < clif->hChSys->colors_count; k++ ) { - msg_len += sprintf(mout, "[ %s ] : %s", command, clif->hChSys->colors_name[k]); + for( k = 0; k < channel->config->colors_count; k++ ) { + msg_len += sprintf(mout, "[ %s ] : %s", command, channel->config->colors_name[k]); WFIFOHEAD(fd,msg_len + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = msg_len + 12; WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = clif->hChSys->colors[k]; + WFIFOL(fd,8) = channel->config->colors[k]; safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); WFIFOSET(fd, msg_len + 12); } @@ -9210,24 +9211,24 @@ ACMD(fontcolor) { return true; } - for( k = 0; k < clif->hChSys->colors_count; k++ ) { - if (strcmpi(message, clif->hChSys->colors_name[k]) == 0) + for( k = 0; k < channel->config->colors_count; k++ ) { + if (strcmpi(message, channel->config->colors_name[k]) == 0) break; } - if( k == clif->hChSys->colors_count ) { + if( k == channel->config->colors_count ) { sprintf(atcmd_output, msg_txt(1411), message);// Unknown color '%s' clif->message(fd, atcmd_output); return false; } sd->fontcolor = k + 1; - msg_len += sprintf(mout, "Color changed to '%s'", clif->hChSys->colors_name[k]); + msg_len += sprintf(mout, "Color changed to '%s'", channel->config->colors_name[k]); WFIFOHEAD(fd,msg_len + 12); WFIFOW(fd,0) = 0x2C1; WFIFOW(fd,2) = msg_len + 12; WFIFOL(fd,4) = 0; - WFIFOL(fd,8) = clif->hChSys->colors[k]; + WFIFOL(fd,8) = channel->config->colors[k]; safestrncpy((char*)WFIFOP(fd,12), mout, msg_len); WFIFOSET(fd, msg_len + 12); return true; -- cgit v1.2.3-70-g09d2 From fe55c7980099b2813a182cdfcc571df705601a4a Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 22 Jan 2015 01:06:07 +0100 Subject: Minor channel system refactoring Signed-off-by: Haru --- src/map/atcommand.c | 90 ++++++++----------- src/map/channel.c | 190 ++++++++++++++++++++++++++++++++--------- src/map/channel.h | 18 +++- src/map/clif.c | 2 +- src/map/guild.c | 8 +- tools/HPMHookGen/HPMHookGen.pl | 2 + 6 files changed, 203 insertions(+), 107 deletions(-) (limited to 'src/map/atcommand.c') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 60f0fc8ed..bf99d4c20 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8649,7 +8649,7 @@ ACMD(join) { clif->message(fd, atcmd_output); return false; } - if( chan->pass[0] != '\0' && strcmp(chan->pass,pass) != 0 ) { + if( chan->password[0] != '\0' && strcmp(chan->password,pass) != 0 ) { if( pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { sd->stealth = true; } else { @@ -8665,7 +8665,7 @@ ACMD(join) { return false; } - if (!(chan->opt & HCS_OPT_ANNOUNCE_JOIN)) { + if (!(chan->options & HCS_OPT_ANNOUNCE_JOIN)) { sprintf(atcmd_output, msg_txt(1403),name); // You're now in the '%s' channel clif->message(fd, atcmd_output); } @@ -8767,13 +8767,11 @@ ACMD(channel) { return false; } - CREATE(chan, struct channel_data, 1); - channel->create(chan,sub1 + 1,sub2,0); - + chan = channel->create(HCS_TYPE_PRIVATE, sub1 + 1, 0); + channel->set_password(chan, sub2); chan->owner = sd->status.char_id; - chan->type = HCS_TYPE_PRIVATE; - if( !( chan->opt & HCS_OPT_ANNOUNCE_JOIN ) ) { + if( !( chan->options & HCS_OPT_ANNOUNCE_JOIN ) ) { sprintf(atcmd_output, msg_txt(1403),sub1); // You're now in the '%s' channel clif->message(fd, atcmd_output); } @@ -8911,8 +8909,8 @@ ACMD(channel) { } else if (strcmpi(subcmd,"ban") == 0) { // sub1 = channel name; sub2 = unused; sub3 = unused struct map_session_data *pl_sd = NULL; - struct channel_ban_entry *entry = NULL; char sub4[NAME_LENGTH]; ///< player name + enum channel_operation_status ret = HCS_STATUS_OK; if (sub1[0] != '#') { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -8925,12 +8923,6 @@ ACMD(channel) { return false; } - if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { - sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' - clif->message(fd, atcmd_output); - return false; - } - if (!message || !*message || sscanf(message, "%19s %19s %23[^\n]", subcmd, sub1, sub4) < 3) { sprintf(atcmd_output, msg_txt(1434), sub4);// Player '%s' was not found clif->message(fd, atcmd_output); @@ -8943,25 +8935,24 @@ ACMD(channel) { return false; } - if (pc_has_permission(pl_sd, PC_PERM_HCHSYS_ADMIN)) { - clif->message(fd, msg_txt(1464)); // Ban failed, not possible to ban this user. + ret = channel->ban(chan, sd, pl_sd); + + if (ret == HCS_STATUS_NOPERM) { + sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' + clif->message(fd, atcmd_output); return false; } - if (chan->banned && idb_exists(chan->banned,pl_sd->status.account_id)) { + if (ret == HCS_STATUS_ALREADY) { sprintf(atcmd_output, msg_txt(1465), pl_sd->status.name);// Player '%s' is already banned from this channel clif->message(fd, atcmd_output); return false; } - if (!chan->banned) - chan->banned = idb_alloc(DB_OPT_BASE|DB_OPT_ALLOW_NULL_DATA|DB_OPT_RELEASE_DATA); - - CREATE(entry, struct channel_ban_entry, 1); - safestrncpy(entry->name, pl_sd->status.name, NAME_LENGTH); - idb_put(chan->banned, pl_sd->status.account_id, entry); - - channel->leave(chan,pl_sd); + if (ret != HCS_STATUS_OK/*ret == HCS_STATUS_FAIL*/) { + clif->message(fd, msg_txt(1464)); // Ban failed, not possible to ban this user. + return false; + } sprintf(atcmd_output, msg_txt(1437),pl_sd->status.name,sub1); // Player '%s' has now been banned from '%s' channel clif->message(fd, atcmd_output); @@ -8969,6 +8960,7 @@ ACMD(channel) { // sub1 = channel name; sub2 = unused; sub3 = unused struct map_session_data *pl_sd = NULL; char sub4[NAME_LENGTH]; ///< player name + enum channel_operation_status ret = HCS_STATUS_OK; if (sub1[0] != '#') { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -8979,42 +8971,33 @@ ACMD(channel) { clif->message(fd, atcmd_output); return false; } - if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { - sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' - clif->message(fd, atcmd_output); - return false; - } - if (!chan->banned) { - sprintf(atcmd_output, msg_txt(1439), sub1);// Channel '%s' has no banned players + if (!message || !*message || sscanf(message, "%19s %19s %23[^\n]", subcmd, sub1, sub4) < 3) { + sprintf(atcmd_output, msg_txt(1434), sub4);// Player '%s' was not found clif->message(fd, atcmd_output); return false; } - if (!message || !*message || sscanf(message, "%19s %19s %23[^\n]", subcmd, sub1, sub4) < 3) { + if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4)) == NULL) { sprintf(atcmd_output, msg_txt(1434), sub4);// Player '%s' was not found clif->message(fd, atcmd_output); return false; } - if (sub4[0] == '\0' || (pl_sd = map->nick2sd(sub4)) == NULL) { - sprintf(atcmd_output, msg_txt(1434), sub4);// Player '%s' was not found + ret = channel->unban(chan, sd, pl_sd); + if (ret == HCS_STATUS_NOPERM) { + sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!idb_exists(chan->banned,pl_sd->status.account_id)) { + if (ret == HCS_STATUS_ALREADY) { sprintf(atcmd_output, msg_txt(1440), pl_sd->status.name);// Player '%s' is not banned from this channel clif->message(fd, atcmd_output); return false; } - idb_remove(chan->banned, pl_sd->status.account_id); - if (!db_size(chan->banned)) { - db_destroy(chan->banned); - chan->banned = NULL; - } - sprintf(atcmd_output, msg_txt(1441),pl_sd->status.name,sub1); // Player '%s' has now been unbanned from the '%s' channel clif->message(fd, atcmd_output); } else if (strcmpi(subcmd,"unbanall") == 0) { + enum channel_operation_status ret = HCS_STATUS_OK; // sub1 = channel name; sub2 = unused; sub3 = unused if (sub1[0] != '#') { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' @@ -9025,18 +9008,17 @@ ACMD(channel) { clif->message(fd, atcmd_output); return false; } - if (chan->owner != sd->status.char_id && !pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + ret = channel->unban(chan, sd, NULL); + if (ret == HCS_STATUS_NOPERM) { sprintf(atcmd_output, msg_txt(1412), sub1);// You're not the owner of channel '%s' clif->message(fd, atcmd_output); return false; } - if (!chan->banned) { + if (ret == HCS_STATUS_ALREADY) { sprintf(atcmd_output, msg_txt(1439), sub1);// Channel '%s' has no banned players clif->message(fd, atcmd_output); return false; } - db_destroy(chan->banned); - chan->banned = NULL; sprintf(atcmd_output, msg_txt(1442),sub1); // Removed all bans from '%s' channel clif->message(fd, atcmd_output); @@ -9124,12 +9106,12 @@ ACMD(channel) { sprintf(atcmd_output, msg_txt(1466), opt_str[k]);// For '%s' you need the amount of seconds (from 0 to 10) clif->message(fd, atcmd_output); return false; - } else if (chan->opt & k) { + } else if (chan->options & k) { sprintf(atcmd_output, msg_txt(1449), opt_str[k],opt_str[k]); // option '%s' is already enabled, if you'd like to disable it type '@channel setopt %s 0' clif->message(fd, atcmd_output); return false; } else { - chan->opt |= k; + channel->set_options(chan, chan->options | k); sprintf(atcmd_output, msg_txt(1450), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s' clif->message(fd, atcmd_output); return true; @@ -9143,13 +9125,13 @@ ACMD(channel) { return false; } if (v == 0) { - chan->opt &=~ k; + channel->set_options(chan, chan->options&~k); chan->msg_delay = 0; sprintf(atcmd_output, msg_txt(1453), opt_str[k],chan->name,v);// option '%s' is now disabled for channel '%s' clif->message(fd, atcmd_output); return true; } else { - chan->opt |= k; + channel->set_options(chan, chan->options | k); chan->msg_delay = v; sprintf(atcmd_output, msg_txt(1452), opt_str[k],chan->name,v);// option '%s' is now enabled for channel '%s' with %d seconds clif->message(fd, atcmd_output); @@ -9157,22 +9139,22 @@ ACMD(channel) { } } else { if (v) { - if (chan->opt & k) { + if (chan->options & k) { sprintf(atcmd_output, msg_txt(1449), opt_str[k],opt_str[k]); // option '%s' is already enabled, if you'd like to disable it type '@channel opt %s 0' clif->message(fd, atcmd_output); return false; } else { - chan->opt |= k; + channel->set_options(chan, chan->options | k); sprintf(atcmd_output, msg_txt(1454), opt_str[k],chan->name);//option '%s' is now enabled for channel '%s' clif->message(fd, atcmd_output); } } else { - if (!(chan->opt & k)) { + if (!(chan->options & k)) { sprintf(atcmd_output, msg_txt(1454), opt_str[k],chan->name); // option '%s' is not enabled on channel '%s' clif->message(fd, atcmd_output); return false; } else { - chan->opt &=~ k; + channel->set_options(chan, chan->options&~k); sprintf(atcmd_output, msg_txt(1453), opt_str[k],chan->name);// option '%s' is now disabled for channel '%s' clif->message(fd, atcmd_output); return true; diff --git a/src/map/channel.c b/src/map/channel.c index 6ebe4650d..b0640eeff 100644 --- a/src/map/channel.c +++ b/src/map/channel.c @@ -19,6 +19,7 @@ #include "../common/conf.h" #include "../common/db.h" #include "../common/malloc.h" +#include "../common/nullpo.h" #include "../common/random.h" #include "../common/showmsg.h" #include "../common/socket.h" @@ -30,24 +31,142 @@ struct channel_interface channel_s; static struct Channel_Config channel_config; -void channel_create(struct channel_data *chan, char *name, char *pass, unsigned char color) +/** + * Creates a chat channel. + * + * If the channel type isn't HCS_TYPE_MAP or HCS_TYPE_ALLY, the channel is added to the channel->db. + * + * @param type The channel type. + * @param name The channel name. + * @param color The channel chat color. + * @return A pointer to the created channel. + */ +struct channel_data *channel_create(enum channel_types type, const char *name, unsigned char color) { + struct channel_data *chan; + CREATE(chan, struct channel_data, 1); chan->users = idb_alloc(DB_OPT_BASE); if (name) safestrncpy(chan->name, name, HCS_NAME_LENGTH); chan->color = color; - if (!pass) - chan->pass[0] = '\0'; - else - safestrncpy(chan->pass, pass, HCS_NAME_LENGTH); - chan->opt = HCS_OPT_BASE; + chan->options = HCS_OPT_BASE; chan->banned = NULL; chan->msg_delay = 0; + chan->type = type; if (chan->type != HCS_TYPE_MAP && chan->type != HCS_TYPE_ALLY) strdb_put(channel->db, chan->name, chan); + return chan; +} + +/** + * Sets a chat channel password. + * + * @param chan The channel to edit. + * @param pass The password to set. Pass NULL to remove existing passwords. + */ +void channel_set_password(struct channel_data *chan, const char *password) +{ + nullpo_retv(chan); + if (password) + safestrncpy(chan->password, password, HCS_NAME_LENGTH); + else + chan->password[0] = '\0'; +} + +/** + * Bans a character from the given channel. + * + * @param chan The channel. + * @param ssd The source character, if any. + * @param tsd The target character. + * @retval HCS_STATUS_OK if the operation succeeded. + * @retval HCS_STATUS_ALREADY if the target character is already banned. + * @retval HCS_STATUS_NOPERM if the source character doesn't have enough permissions. + * @retval HCS_STATUS_FAIL in case of generic failure. + */ +enum channel_operation_status channel_ban(struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd) +{ + struct channel_ban_entry *entry = NULL; + + nullpo_retr(HCS_STATUS_FAIL, chan); + nullpo_retr(HCS_STATUS_FAIL, tsd); + + if (ssd && chan->owner != ssd->status.char_id && !pc_has_permission(ssd, PC_PERM_HCHSYS_ADMIN)) + return HCS_STATUS_NOPERM; + + if (pc_has_permission(tsd, PC_PERM_HCHSYS_ADMIN)) + return HCS_STATUS_FAIL; + + if (chan->banned && idb_exists(chan->banned, tsd->status.account_id)) + return HCS_STATUS_ALREADY; + + if (!chan->banned) + chan->banned = idb_alloc(DB_OPT_BASE|DB_OPT_ALLOW_NULL_DATA|DB_OPT_RELEASE_DATA); + + CREATE(entry, struct channel_ban_entry, 1); + safestrncpy(entry->name, tsd->status.name, NAME_LENGTH); + idb_put(chan->banned, tsd->status.account_id, entry); + + channel->leave(chan, tsd); + + return HCS_STATUS_OK; +} + +/** + * Unbans a character from the given channel. + * + * @param chan The channel. + * @param ssd The source character, if any. + * @param tsd The target character. If no target character is specified, all characters are unbanned. + * @retval HCS_STATUS_OK if the operation succeeded. + * @retval HCS_STATUS_ALREADY if the target character is not banned. + * @retval HCS_STATUS_NOPERM if the source character doesn't have enough permissions. + * @retval HCS_STATUS_FAIL in case of generic failure. + */ +enum channel_operation_status channel_unban(struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd) +{ + nullpo_retr(HCS_STATUS_FAIL, chan); + + if (ssd && chan->owner != ssd->status.char_id && !pc_has_permission(ssd, PC_PERM_HCHSYS_ADMIN)) + return HCS_STATUS_NOPERM; + + if (!chan->banned) + return HCS_STATUS_ALREADY; + + if (!tsd) { + // Unban all + db_destroy(chan->banned); + chan->banned = NULL; + return HCS_STATUS_OK; + } + + // Unban one + if (!idb_exists(chan->banned, tsd->status.account_id)) + return HCS_STATUS_ALREADY; + + idb_remove(chan->banned, tsd->status.account_id); + if (!db_size(chan->banned)) { + db_destroy(chan->banned); + chan->banned = NULL; + } + + return HCS_STATUS_OK; +} + +/** + * Sets or edits a channel's options. + * + * @param chan The channel. + * @param options The new options set to apply. + */ +void channel_set_options(struct channel_data *chan, unsigned int options) +{ + nullpo_retv(chan); + + chan->options = options; } /** @@ -87,7 +206,7 @@ void channel_join(struct channel_data *chan, struct map_session_data *sd) if (sd->stealth) { sd->stealth = false; - } else if (chan->opt & HCS_OPT_ANNOUNCE_JOIN) { + } else if (chan->options & HCS_OPT_ANNOUNCE_JOIN) { char message[60]; sprintf(message, "#%s '%s' joined",chan->name,sd->status.name); clif->channel_msg(chan,sd,message); @@ -102,28 +221,23 @@ void channel_join(struct channel_data *chan, struct map_session_data *sd) void channel_map_join(struct map_session_data *sd) { - if( sd->state.autotrade || sd->state.standalone ) + if (sd->state.autotrade || sd->state.standalone) return; - if( !map->list[sd->bl.m].channel ) { - - if (map->list[sd->bl.m].flag.chsysnolocalaj || (map->list[sd->bl.m].instance_id >= 0 && instance->list[map->list[sd->bl.m].instance_id].owner_type != IOT_NONE) ) + if (!map->list[sd->bl.m].channel) { + if (map->list[sd->bl.m].flag.chsysnolocalaj || (map->list[sd->bl.m].instance_id >= 0 && instance->list[map->list[sd->bl.m].instance_id].owner_type != IOT_NONE)) return; - CREATE(map->list[sd->bl.m].channel, struct channel_data , 1); - safestrncpy(map->list[sd->bl.m].channel->name, channel->config->local_name, HCS_NAME_LENGTH); - map->list[sd->bl.m].channel->type = HCS_TYPE_MAP; + map->list[sd->bl.m].channel = channel->create(HCS_TYPE_MAP, channel->config->local_name, channel->config->local_color); map->list[sd->bl.m].channel->m = sd->bl.m; - - channel->create(map->list[sd->bl.m].channel, NULL, NULL, channel->config->local_color); } - if( map->list[sd->bl.m].channel->banned && idb_exists(map->list[sd->bl.m].channel->banned, sd->status.account_id) ) { + if (map->list[sd->bl.m].channel->banned && idb_exists(map->list[sd->bl.m].channel->banned, sd->status.account_id)) { return; } channel->join(map->list[sd->bl.m].channel,sd); - if( !( map->list[sd->bl.m].channel->opt & HCS_OPT_ANNOUNCE_JOIN ) ) { + if (!( map->list[sd->bl.m].channel->options & HCS_OPT_ANNOUNCE_JOIN )) { char mout[60]; sprintf(mout, msg_txt(1435), channel->config->local_name, map->list[sd->bl.m].name); // You're now in the '#%s' channel for '%s' clif->colormes(sd->fd, COLOR_DEFAULT, mout); @@ -142,7 +256,7 @@ void channel_leave(struct channel_data *chan, struct map_session_data *sd) if( !db_size(chan->users) && chan->type == HCS_TYPE_PRIVATE ) { channel->delete(chan); - } else if( !channel->config->closing && (chan->opt & HCS_OPT_ANNOUNCE_JOIN) ) { + } else if( !channel->config->closing && (chan->options & HCS_OPT_ANNOUNCE_JOIN) ) { char message[60]; sprintf(message, "#%s '%s' left",chan->name,sd->status.name); clif->channel_msg(chan,sd,message); @@ -188,7 +302,7 @@ void channel_quit_guild(struct map_session_data *sd) if (!db_size(chan->users) && chan->type == HCS_TYPE_PRIVATE) { channel->delete(chan); - } else if (!channel->config->closing && (chan->opt & HCS_OPT_ANNOUNCE_JOIN)) { + } else if (!channel->config->closing && (chan->options & HCS_OPT_ANNOUNCE_JOIN)) { char message[60]; sprintf(message, "#%s '%s' left",chan->name,sd->status.name); clif->channel_msg(chan,sd,message); @@ -230,7 +344,7 @@ void channel_quit(struct map_session_data *sd) if (!db_size(chan->users) && chan->type == HCS_TYPE_PRIVATE) { channel->delete(chan); - } else if (!channel->config->closing && (chan->opt & HCS_OPT_ANNOUNCE_JOIN)) { + } else if (!channel->config->closing && (chan->options & HCS_OPT_ANNOUNCE_JOIN)) { char message[60]; sprintf(message, "#%s '%s' left",chan->name,sd->status.name); clif->channel_msg(chan,sd,message); @@ -512,14 +626,7 @@ void read_channels_config(void) } if (channel->config->irc) { - struct channel_data *chd; - CREATE(chd, struct channel_data, 1); - - safestrncpy(chd->name, channel->config->irc_name, HCS_NAME_LENGTH); - chd->type = HCS_TYPE_IRC; - - channel->create(chd, NULL, NULL, channel->config->irc_color); - ircbot->channel = chd; + ircbot->channel = channel->create(HCS_TYPE_IRC, channel->config->irc_name, channel->config->irc_color); } if( (channels = libconfig->setting_get_member(settings, "default_channels")) != NULL ) { @@ -529,27 +636,21 @@ void read_channels_config(void) config_setting_t *chan = libconfig->setting_get_elem(channels, i); const char *name = config_setting_name(chan); const char *color = libconfig->setting_get_string_elem(channels,i); - struct channel_data *chd; - for (k = 0; k < channel->config->colors_count; k++) { - if (strcmpi(channel->config->colors_name[k],color) == 0) - break; - } - if( k == channel->config->colors_count) { + ARR_FIND(0, channel->config->colors_count, k, strcmpi(channel->config->colors_name[k],color) == 0); + if (k == channel->config->colors_count) { ShowError("channels.conf: unknown color '%s' for channel '%s', skipping channel...\n",color,name); continue; } - if( strcmpi(name, channel->config->local_name) == 0 || strcmpi(name, channel->config->ally_name) == 0 || strcmpi(name, channel->config->irc_name) == 0 || strdb_exists(channel->db, name) ) { + if (strcmpi(name, channel->config->local_name) == 0 + || strcmpi(name, channel->config->ally_name) == 0 + || strcmpi(name, channel->config->irc_name) == 0 + || strdb_exists(channel->db, name)) { ShowError("channels.conf: duplicate channel '%s', skipping channel...\n",name); continue; } - CREATE( chd, struct channel_data, 1 ); - - safestrncpy(chd->name, name, HCS_NAME_LENGTH); - chd->type = HCS_TYPE_PUBLIC; - - channel->create(chd,NULL,NULL,k); + channel->create(HCS_TYPE_PUBLIC, name, k); } } @@ -605,6 +706,11 @@ void channel_defaults(void) channel->config = &channel_config; channel->create = channel_create; + channel->set_password = channel_set_password; + channel->ban = channel_ban; + channel->unban = channel_unban; + channel->set_options = channel_set_options; + channel->send = channel_send; channel->join = channel_join; channel->leave = channel_leave; diff --git a/src/map/channel.h b/src/map/channel.h index dd434d0cc..11ba968a9 100644 --- a/src/map/channel.h +++ b/src/map/channel.h @@ -35,6 +35,13 @@ enum channel_types { HCS_TYPE_IRC = 4, }; +enum channel_operation_status { + HCS_STATUS_OK = 0, + HCS_STATUS_FAIL, + HCS_STATUS_ALREADY, + HCS_STATUS_NOPERM, +}; + /** * Structures **/ @@ -59,11 +66,11 @@ struct channel_ban_entry { struct channel_data { char name[HCS_NAME_LENGTH]; - char pass[HCS_NAME_LENGTH]; + char password[HCS_NAME_LENGTH]; unsigned char color; DBMap *users; DBMap *banned; - unsigned int opt; + unsigned int options; unsigned int owner; enum channel_types type; uint16 m; @@ -78,7 +85,12 @@ struct channel_interface { int (*init) (bool minimal); void (*final) (void); - void (*create) (struct channel_data *chan, char *name, char *pass, unsigned char color); + struct channel_data *(*create) (enum channel_types type, const char *name, unsigned char color); + void (*set_password) (struct channel_data *chan, const char *password); + enum channel_operation_status (*ban) (struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd); + enum channel_operation_status (*unban) (struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd); + void (*set_options) (struct channel_data *chan, unsigned int options); + void (*send) (struct channel_data *chan, struct map_session_data *sd, const char *msg); void (*join) (struct channel_data *chan, struct map_session_data *sd); void (*leave) (struct channel_data *chan, struct map_session_data *sd); diff --git a/src/map/clif.c b/src/map/clif.c index cd449fc5a..10ab7121a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10064,7 +10064,7 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) } if( k < sd->channel_count ) { channel->send(chan,sd,message); - } else if( chan->pass[0] == '\0' && !(chan->banned && idb_exists(chan->banned, sd->status.account_id)) ) { + } else if( chan->password[0] == '\0' && !(chan->banned && idb_exists(chan->banned, sd->status.account_id)) ) { if( chan->type == HCS_TYPE_ALLY ) { struct guild *g = sd->guild; for (k = 0; k < MAX_GUILDALLIANCE; k++) { diff --git a/src/map/guild.c b/src/map/guild.c index 2ee76ba98..3e71e99dc 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -472,13 +472,7 @@ int guild_recv_info(struct guild *sg) { g->instances = 0; idb_put(guild->db,sg->guild_id,g); if (channel->config->ally) { - struct channel_data *chan; - - CREATE(chan, struct channel_data , 1); - safestrncpy(chan->name, channel->config->ally_name, HCS_NAME_LENGTH); - chan->type = HCS_TYPE_ALLY; - - channel->create(chan, NULL, NULL, channel->config->ally_color); + struct channel_data *chan = channel->create(HCS_TYPE_ALLY, channel->config->ally_name, channel->config->ally_color); if (channel->config->ally_autojoin) { struct s_mapiterator* iter = mapit_getallusers(); struct guild *tg[MAX_GUILDALLIANCE]; diff --git a/tools/HPMHookGen/HPMHookGen.pl b/tools/HPMHookGen/HPMHookGen.pl index 03b32394c..4fa548e44 100755 --- a/tools/HPMHookGen/HPMHookGen.pl +++ b/tools/HPMHookGen/HPMHookGen.pl @@ -217,6 +217,8 @@ sub parse($$) { $rtinit = ' = BL_NUL'; } elsif ($x =~ /^enum\s+homun_type$/) { # Known enum homun_type $rtinit = ' = HT_INVALID'; + } elsif ($x =~ /^enum\s+channel_operation_status$/) { # Known enum channel_operation_status + $rtinit = ' = HCS_STATUS_FAIL'; } elsif ($x =~ /^enum\s+bg_queue_types$/) { # Known enum bg_queue_types $rtinit = ' = BGQT_INVALID'; } elsif ($x =~ /^struct\s+.*$/ or $x eq 'DBData') { # Structs -- cgit v1.2.3-70-g09d2 From 5066af1700e95b5db24f9998cf1ff052b45f5fa0 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 22 Jan 2015 18:10:46 +0100 Subject: Channels refactoring: join Signed-off-by: Haru --- src/map/atcommand.c | 57 +++++++++++------------------------ src/map/channel.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++----- src/map/channel.h | 6 +++- src/map/clif.c | 15 ++-------- src/map/guild.c | 18 +++-------- src/map/pc.h | 1 - 6 files changed, 107 insertions(+), 76 deletions(-) (limited to 'src/map/atcommand.c') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index bf99d4c20..0f33a387c 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8612,9 +8612,11 @@ ACMD(cart) { #undef MC_CART_MDFY } /* [Ind/Hercules] */ -ACMD(join) { +ACMD(join) +{ struct channel_data *chan = NULL; char name[HCS_NAME_LENGTH], pass[HCS_NAME_LENGTH]; + enum channel_operation_status ret = HCS_STATUS_OK; if (!message || !*message || sscanf(message, "%19s %19s", name, pass) < 1) { sprintf(atcmd_output, msg_txt(1399),command); // Unknown Channel (usage: %s <#channel_name>) @@ -8632,56 +8634,35 @@ ACMD(join) { struct guild *g = sd->guild; if( !g ) return false;/* unlikely, but we wont let it crash anyway. */ chan = g->channel; - } else if( !( chan = strdb_get(channel->db, name + 1) ) ) { - sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) - clif->message(fd, atcmd_output); - return false; + } else { + chan = strdb_get(channel->db, name + 1); } - if( !chan ) { + if(!chan) { sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) clif->message(fd, atcmd_output); return false; } - if( idb_exists(chan->users, sd->status.char_id) ) { + ret = channel->join(chan, sd, pass, false); + + if (ret == HCS_STATUS_ALREADY) { sprintf(atcmd_output, msg_txt(1436),name); // You're already in the '%s' channel clif->message(fd, atcmd_output); return false; } - if( chan->password[0] != '\0' && strcmp(chan->password,pass) != 0 ) { - if( pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN) ) { - sd->stealth = true; - } else { - sprintf(atcmd_output, msg_txt(1401),name,command); // '%s' Channel is password protected (usage: %s <#channel_name> ) - clif->message(fd, atcmd_output); - return false; - } - } - if( chan->banned && idb_exists(chan->banned, sd->status.account_id) ) { - sprintf(atcmd_output, msg_txt(1438),name); // You cannot join the '%s' channel because you've been banned from it + if (ret == HCS_STATUS_NOPERM) { + sprintf(atcmd_output, msg_txt(1401),name,command); // '%s' Channel is password protected (usage: %s <#channel_name> ) clif->message(fd, atcmd_output); return false; } - if (!(chan->options & HCS_OPT_ANNOUNCE_JOIN)) { - sprintf(atcmd_output, msg_txt(1403),name); // You're now in the '%s' channel + if (ret == HCS_STATUS_BANNED) { + sprintf(atcmd_output, msg_txt(1438),name); // You cannot join the '%s' channel because you've been banned from it clif->message(fd, atcmd_output); + return false; } - if( chan->type == HCS_TYPE_ALLY ) { - struct guild *g = sd->guild; - int i; - for (i = 0; i < MAX_GUILDALLIANCE; i++) { - struct guild *sg = NULL; - if( g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id) ) ) { - if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) { - channel->join(sg->channel,sd); - } - } - } - } - channel->join(chan,sd); return true; } @@ -8750,6 +8731,7 @@ ACMD(channel) { if (strcmpi(subcmd,"create") == 0 && (channel->config->allow_user_channel_creation || pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN))) { // sub1 = channel name; sub2 = password; sub3 = unused size_t len = strlen(sub1); + const char *pass = *sub2 ? sub2 : NULL; if (sub1[0] != '#') { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; @@ -8768,15 +8750,10 @@ ACMD(channel) { } chan = channel->create(HCS_TYPE_PRIVATE, sub1 + 1, 0); - channel->set_password(chan, sub2); + channel->set_password(chan, pass); chan->owner = sd->status.char_id; - if( !( chan->options & HCS_OPT_ANNOUNCE_JOIN ) ) { - sprintf(atcmd_output, msg_txt(1403),sub1); // You're now in the '%s' channel - clif->message(fd, atcmd_output); - } - - channel->join(chan,sd); + channel->join(chan, sd, pass, false); } else if (strcmpi(subcmd,"list") == 0) { // sub1 = list type; sub2 = unused; sub3 = unused if (sub1[0] != '\0' && strcmpi(sub1,"colors") == 0) { diff --git a/src/map/channel.c b/src/map/channel.c index b0640eeff..49f5c9daa 100644 --- a/src/map/channel.c +++ b/src/map/channel.c @@ -196,17 +196,25 @@ void channel_send(struct channel_data *chan, struct map_session_data *sd, const } } -void channel_join(struct channel_data *chan, struct map_session_data *sd) +/** + * Joins a channel, without any permission checks. + * + * @param chan The channel to join + * @param sd The character + * @param stealth If true, hide join announcements. + */ +void channel_join_sub(struct channel_data *chan, struct map_session_data *sd, bool stealth) { + nullpo_retv(chan); + nullpo_retv(sd); + if (idb_put(chan->users, sd->status.char_id, sd)) return; RECREATE(sd->channels, struct channel_data *, ++sd->channel_count); sd->channels[ sd->channel_count - 1 ] = chan; - if (sd->stealth) { - sd->stealth = false; - } else if (chan->options & HCS_OPT_ANNOUNCE_JOIN) { + if (!stealth && (chan->options&HCS_OPT_ANNOUNCE_JOIN)) { char message[60]; sprintf(message, "#%s '%s' joined",chan->name,sd->status.name); clif->channel_msg(chan,sd,message); @@ -219,6 +227,69 @@ void channel_join(struct channel_data *chan, struct map_session_data *sd) } +/** + * Joins a channel. + * + * Ban and password checks are performed before joining the channel. + * If the channel is an HCS_TYPE_ALLY channel, alliance channels are automatically joined. + * + * @param chan The channel to join + * @param sd The character + * @param password The specified join password, if any + * @param silent If true, suppress the "You're now in the channel" greeting message + * @retval HCS_STATUS_OK if the operation succeeded + * @retval HCS_STATUS_ALREADY if the character is already in the channel + * @retval HCS_STATUS_NOPERM if the specified password doesn't match + * @retval HCS_STATUS_BANNED if the character is in the channel's ban list + * @retval HCS_STATUS_FAIL in case of generic error + */ +enum channel_operation_status channel_join(struct channel_data *chan, struct map_session_data *sd, const char *password, bool silent) +{ + bool stealth = false; + + nullpo_retr(HCS_STATUS_FAIL, chan); + nullpo_retr(HCS_STATUS_FAIL, sd); + + if (idb_exists(chan->users, sd->status.char_id)) { + return HCS_STATUS_ALREADY; + } + + if (chan->password[0] != '\0' && strcmp(chan->password, password) != 0) { + if (pc_has_permission(sd, PC_PERM_HCHSYS_ADMIN)) { + stealth = true; + } else { + return HCS_STATUS_NOPERM; + } + } + + if (chan->banned && idb_exists(chan->banned, sd->status.account_id)) { + return HCS_STATUS_BANNED; + } + + if (!silent && !(chan->options&HCS_OPT_ANNOUNCE_JOIN)) { + char output[CHAT_SIZE_MAX]; + sprintf(output, msg_txt(1403), chan->name); // You're now in the '%s' channel + clif->message(sd->fd, output); + } + + if (chan->type == HCS_TYPE_ALLY) { + struct guild *g = sd->guild; + int i; + for (i = 0; i < MAX_GUILDALLIANCE; i++) { + struct guild *sg = NULL; + if (g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id))) { + if (!(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) { + channel->join_sub(sg->channel, sd, stealth); + } + } + } + } + + channel->join_sub(chan, sd, stealth); + + return HCS_STATUS_OK; +} + void channel_map_join(struct map_session_data *sd) { if (sd->state.autotrade || sd->state.standalone) @@ -235,7 +306,7 @@ void channel_map_join(struct map_session_data *sd) return; } - channel->join(map->list[sd->bl.m].channel,sd); + channel->join_sub(map->list[sd->bl.m].channel,sd, false); if (!( map->list[sd->bl.m].channel->options & HCS_OPT_ANNOUNCE_JOIN )) { char mout[60]; @@ -414,7 +485,7 @@ void channel_guild_join(struct guild *g1,struct guild *g2) for(j = 0; j < g2->max_member; j++) { if( (sd = g2->member[j].sd) != NULL ) { if( !(g1->channel->banned && idb_exists(g1->channel->banned, sd->status.account_id))) - channel->join(chan,sd); + channel->join_sub(chan,sd, false); } } } @@ -423,7 +494,7 @@ void channel_guild_join(struct guild *g1,struct guild *g2) for(j = 0; j < g1->max_member; j++) { if( (sd = g1->member[j].sd) != NULL ) { if( !(g2->channel->banned && idb_exists(g2->channel->banned, sd->status.account_id))) - channel->join(chan,sd); + channel->join_sub(chan,sd, false); } } } @@ -712,6 +783,7 @@ void channel_defaults(void) channel->set_options = channel_set_options; channel->send = channel_send; + channel->join_sub = channel_join_sub; channel->join = channel_join; channel->leave = channel_leave; channel->delete = channel_delete; diff --git a/src/map/channel.h b/src/map/channel.h index 11ba968a9..8709a9f96 100644 --- a/src/map/channel.h +++ b/src/map/channel.h @@ -40,6 +40,7 @@ enum channel_operation_status { HCS_STATUS_FAIL, HCS_STATUS_ALREADY, HCS_STATUS_NOPERM, + HCS_STATUS_BANNED, }; /** @@ -85,6 +86,7 @@ struct channel_interface { int (*init) (bool minimal); void (*final) (void); + struct channel_data *(*search) (const char *name); struct channel_data *(*create) (enum channel_types type, const char *name, unsigned char color); void (*set_password) (struct channel_data *chan, const char *password); enum channel_operation_status (*ban) (struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd); @@ -92,7 +94,9 @@ struct channel_interface { void (*set_options) (struct channel_data *chan, unsigned int options); void (*send) (struct channel_data *chan, struct map_session_data *sd, const char *msg); - void (*join) (struct channel_data *chan, struct map_session_data *sd); + void (*join_sub) (struct channel_data *chan, struct map_session_data *sd, bool stealth); + enum channel_operation_status (*join) (struct channel_data *chan, struct map_session_data *sd, const char *password, bool silent); + void (*leave) (struct channel_data *chan, struct map_session_data *sd); void (*delete) (struct channel_data *chan); void (*map_join) (struct map_session_data *sd); diff --git a/src/map/clif.c b/src/map/clif.c index 10ab7121a..c66176d45 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10062,20 +10062,9 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) if( sd->channels[k] == chan ) break; } - if( k < sd->channel_count ) { + if (k < sd->channel_count) { channel->send(chan,sd,message); - } else if( chan->password[0] == '\0' && !(chan->banned && idb_exists(chan->banned, sd->status.account_id)) ) { - if( chan->type == HCS_TYPE_ALLY ) { - struct guild *g = sd->guild; - for (k = 0; k < MAX_GUILDALLIANCE; k++) { - struct guild *sg = NULL; - if( g->alliance[k].opposition == 0 && g->alliance[k].guild_id && (sg = guild->search(g->alliance[k].guild_id) ) ) { - if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) - channel->join(sg->channel,sd); - } - } - } - channel->join(chan,sd); + } else if (channel->join(chan, sd, NULL, true) == HCS_STATUS_OK) { channel->send(chan,sd,message); } else { clif->message(fd, msg_txt(1402)); diff --git a/src/map/guild.c b/src/map/guild.c index 3e71e99dc..a33efb831 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -489,13 +489,13 @@ int guild_recv_info(struct guild *sg) { if (sd->status.guild_id == sg->guild_id) { // Guild member - channel->join(chan,sd); + channel->join_sub(chan,sd,false); sd->guild = g; for (i = 0; i < MAX_GUILDALLIANCE; i++) { // Join channels from allied guilds if (tg[i] && !(tg[i]->channel->banned && idb_exists(tg[i]->channel->banned, sd->status.account_id))) - channel->join(tg[i]->channel, sd); + channel->join_sub(tg[i]->channel, sd, false); } continue; } @@ -504,7 +504,7 @@ int guild_recv_info(struct guild *sg) { if (tg[i] && sd->status.guild_id == tg[i]->guild_id) { // Shortcut to skip the alliance checks again // Alliance member if( !(chan->banned && idb_exists(chan->banned, sd->status.account_id))) - channel->join(chan, sd); + channel->join_sub(chan, sd, false); } } } @@ -741,17 +741,7 @@ void guild_member_joined(struct map_session_data *sd) sd->guild = g; if (channel->config->ally && channel->config->ally_autojoin) { - struct channel_data *chan = g->channel; - - if( !(chan->banned && idb_exists(chan->banned, sd->status.account_id) ) ) - channel->join(chan,sd); - for (i = 0; i < MAX_GUILDALLIANCE; i++) { - struct guild* sg = NULL; - if( g->alliance[i].opposition == 0 && g->alliance[i].guild_id && (sg = guild->search(g->alliance[i].guild_id) ) ) { - if( !(sg->channel->banned && idb_exists(sg->channel->banned, sd->status.account_id))) - channel->join(sg->channel,sd); - } - } + channel->join(g->channel, sd, NULL, true); } } diff --git a/src/map/pc.h b/src/map/pc.h index 167aa6010..f6b6329b4 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -494,7 +494,6 @@ struct map_session_data { struct channel_data **channels; unsigned char channel_count; struct channel_data *gcbind; - bool stealth; unsigned char fontcolor; unsigned int fontcolor_tid; int64 hchsysch_tick; -- cgit v1.2.3-70-g09d2 From 30ac667346838d1777eed6cf90ce24341c6d2914 Mon Sep 17 00:00:00 2001 From: Haru Date: Thu, 22 Jan 2015 18:37:56 +0100 Subject: Channels refactoring: search Signed-off-by: Haru --- src/map/atcommand.c | 28 ++++++++-------------------- src/map/channel.c | 37 +++++++++++++++++++++++++++++++++++++ src/map/channel.h | 2 +- src/map/clif.c | 28 +++++----------------------- 4 files changed, 51 insertions(+), 44 deletions(-) (limited to 'src/map/atcommand.c') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 0f33a387c..a6e4d7265 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -8623,20 +8623,8 @@ ACMD(join) clif->message(fd, atcmd_output); return false; } - if (channel->config->local && strcmpi(name + 1, channel->config->local_name) == 0) { - if( !map->list[sd->bl.m].channel ) { - channel->map_join(sd); - if( map->list[sd->bl.m].channel ) /* join might have refused, map has chatting capabilities disabled */ - return true; - } else - chan = map->list[sd->bl.m].channel; - } else if (channel->config->ally && sd->status.guild_id && strcmpi(name + 1, channel->config->ally_name) == 0) { - struct guild *g = sd->guild; - if( !g ) return false;/* unlikely, but we wont let it crash anyway. */ - chan = g->channel; - } else { - chan = strdb_get(channel->db, name + 1); - } + + chan = channel->search(name, sd); if(!chan) { sprintf(atcmd_output, msg_txt(1400),name,command); // Unknown Channel '%s' (usage: %s <#channel_name>) @@ -8799,7 +8787,7 @@ ACMD(channel) { return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; @@ -8894,7 +8882,7 @@ ACMD(channel) { return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; @@ -8943,7 +8931,7 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; @@ -8980,7 +8968,7 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; @@ -9009,7 +8997,7 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; @@ -9050,7 +9038,7 @@ ACMD(channel) { clif->message(fd, msg_txt(1405));// Channel name must start with a '#' return false; } - if (!(chan = strdb_get(channel->db, sub1 + 1))) { + if (!(chan = channel->search(sub1, sd))) { sprintf(atcmd_output, msg_txt(1407), sub1);// Channel '%s' is not available clif->message(fd, atcmd_output); return false; diff --git a/src/map/channel.c b/src/map/channel.c index 49f5c9daa..e3cc789e4 100644 --- a/src/map/channel.c +++ b/src/map/channel.c @@ -31,6 +31,42 @@ struct channel_interface channel_s; static struct Channel_Config channel_config; +/** + * Returns the named channel. + * + * @param name The channel name + * @param sd The issuer character, for character-specific channels (i.e. map, ally) + * @return a pointer to the channel, or NULL. + */ +struct channel_data *channel_search(const char *name, struct map_session_data *sd) +{ + const char *realname = name; + if (!realname || !*realname) + return NULL; + if (*realname == '#') { + realname++; + if (!*realname) + return NULL; + } + + if (channel->config->local && strcmpi(realname, channel->config->local_name) == 0) { + if (!sd) + return NULL; + if (!map->list[sd->bl.m].channel) { + channel->map_join(sd); + } + return map->list[sd->bl.m].channel; + } + + if (channel->config->ally && strcmpi(realname, channel->config->ally_name) == 0) { + if (!sd || !sd->status.guild_id || !sd->guild) + return NULL; + return sd->guild->channel; + } + + return strdb_get(channel->db, realname); +} + /** * Creates a chat channel. * @@ -776,6 +812,7 @@ void channel_defaults(void) channel->final = do_final_channel; channel->config = &channel_config; + channel->search = channel_search; channel->create = channel_create; channel->set_password = channel_set_password; channel->ban = channel_ban; diff --git a/src/map/channel.h b/src/map/channel.h index 8709a9f96..39127f3b9 100644 --- a/src/map/channel.h +++ b/src/map/channel.h @@ -86,7 +86,7 @@ struct channel_interface { int (*init) (bool minimal); void (*final) (void); - struct channel_data *(*search) (const char *name); + struct channel_data *(*search) (const char *name, struct map_session_data *sd); struct channel_data *(*create) (enum channel_types type, const char *name, unsigned char color); void (*set_password) (struct channel_data *chan, const char *password); enum channel_operation_status (*ban) (struct channel_data *chan, const struct map_session_data *ssd, struct map_session_data *tsd); diff --git a/src/map/clif.c b/src/map/clif.c index c66176d45..269b72ae1 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10040,31 +10040,13 @@ void clif_parse_WisMessage(int fd, struct map_session_data* sd) return; } } else if( target[0] == '#' ) { - // TODO: Split to channel.c - struct channel_data *chan = NULL; - char* chname = target; + char *chname = target; + struct channel_data *chan = channel->search(chname, sd); - chname++; - - if (channel->config->local && strcmpi(chname, channel->config->local_name) == 0) { - if( !map->list[sd->bl.m].channel ) { - channel->map_join(sd); - } - chan = map->list[sd->bl.m].channel; - } else if (channel->config->ally && sd->status.guild_id && strcmpi(chname, channel->config->ally_name) == 0) { - struct guild *g = sd->guild; - if( !g ) return; - chan = g->channel; - } - if( chan || (chan = strdb_get(channel->db,chname)) ) { + if (chan) { int k; - for( k = 0; k < sd->channel_count; k++ ) { - if( sd->channels[k] == chan ) - break; - } - if (k < sd->channel_count) { - channel->send(chan,sd,message); - } else if (channel->join(chan, sd, NULL, true) == HCS_STATUS_OK) { + ARR_FIND(0, sd->channel_count, k, sd->channels[k] == chan); + if (k < sd->channel_count || channel->join(chan, sd, NULL, true) == HCS_STATUS_OK) { channel->send(chan,sd,message); } else { clif->message(fd, msg_txt(1402)); -- cgit v1.2.3-70-g09d2