#define KEY_EXPIRES "expires"
#define KEY_TRIGGERED "triggered"
-#define CHANNEL_DEFAULT_FLAGS (CHANNEL_INFO_LINES)
+#define CHANNEL_DEFAULT_FLAGS (0)
#define CHANNEL_DEFAULT_OPTIONS "lmoooanpcnat"
/* Administrative messages */
{ "CSMSG_CONFIRM_DEFAULTS", "To reset %s's settings to the defaults, you muse use 'set defaults %s'." },
{ "CSMSG_SETTINGS_DEFAULTED", "All settings for %s have been reset to default values." },
{ "CSMSG_BAD_SETLEVEL", "You cannot change any setting to above your level." },
+ { "CSMSG_BAD_GIVEVOICE", "You cannot change GiveVoice to above GiveOps (%d)." },
+ { "CSMSG_BAD_GIVEOPS", "You cannot change GiveOps to below GiveVoice (%d)." },
+ { "CSMSG_BAD_SETTERS", "You cannot change Setters to above your level." },
{ "CSMSG_INVALID_MODE_LOCK", "$b%s$b is an invalid mode lock." },
{ "CSMSG_INVALID_NUMERIC", "$b%d$b is not a valid choice. Choose one:" },
{ "CSMSG_SET_DEFAULT_TOPIC", "$bDefaultTopic$b %s" },
{ "CSMSG_SET_USERGREETING", "$bUserGreeting$b %s" },
{ "CSMSG_SET_MODES", "$bModes $b %s" },
{ "CSMSG_SET_NODELETE", "$bNoDelete $b %s" },
- { "CSMSG_SET_USERINFO", "$bUserInfo $b %s" },
- { "CSMSG_SET_VOICE", "$bVoice $b %s" },
{ "CSMSG_SET_DYNLIMIT", "$bDynLimit $b %s" },
- { "CSMSG_SET_TOPICSNARF", "$bTopicSnarf $b %s" },
- { "CSMSG_SET_PEONINVITE", "$bPeonInvite $b %s" },
+ { "CSMSG_SET_USERINFO", "$bUserInfo $b %d" },
+ { "CSMSG_SET_GIVE_VOICE", "$bGiveVoice $b %d" },
+ { "CSMSG_SET_TOPICSNARF", "$bTopicSnarf $b %d" },
+ { "CSMSG_SET_INVITEME", "$bInviteMe $b %d" },
{ "CSMSG_SET_ENFOPS", "$bEnfOps $b %d" },
{ "CSMSG_SET_GIVE_OPS", "$bGiveOps $b %d" },
{ "CSMSG_SET_ENFMODES", "$bEnfModes $b %d" },
/* Access information */
{ "CSMSG_IS_CHANSERV", "$b$C$b is the $bchannel service bot$b." },
- { "CSMSG_ACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $b%s$b with no arguments)." },
- { "CSMSG_SQUAT_ACCESS", "You do not have access to any channels." },
+ { "CSMSG_MYACCESS_SELF_ONLY", "You may only see the list of infolines for yourself (by using $b%s$b with no arguments)." },
+ { "CSMSG_SQUAT_ACCESS", "$b%s$b does not have access to any channels." },
{ "CSMSG_INFOLINE_LIST", "Showing all channel entries for account $b%s$b:" },
{ "CSMSG_USER_NO_ACCESS", "%s lacks access to %s." },
{ "CSMSG_USER_HAS_ACCESS", "%s has access $b%d$b in %s." },
char *db_name;
unsigned short default_value;
unsigned int old_idx;
+ unsigned int old_flag;
+ unsigned short flag_value;
} levelOptions[] = {
- { "CSMSG_SET_GIVE_OPS", "giveops", 200, 2 },
- { "CSMSG_SET_ENFOPS", "enfops", 300, 1 },
- { "CSMSG_SET_ENFMODES", "enfmodes", 200, 3 },
- { "CSMSG_SET_ENFTOPIC", "enftopic", 200, 4 },
- { "CSMSG_SET_PUBCMD", "pubcmd", 0, 5 },
- { "CSMSG_SET_SETTERS", "setters", 400, 7 },
- { "CSMSG_SET_CTCPUSERS", "ctcpusers", 0, 9 }
+ { "CSMSG_SET_GIVE_VOICE", "givevoice", 100, ~0, CHANNEL_VOICE_ALL, 0 },
+ { "CSMSG_SET_GIVE_OPS", "giveops", 200, 2, 0, 0 },
+ { "CSMSG_SET_ENFOPS", "enfops", 300, 1, 0, 0 },
+ { "CSMSG_SET_ENFMODES", "enfmodes", 200, 3, 0, 0 },
+ { "CSMSG_SET_ENFTOPIC", "enftopic", 200, 4, 0, 0 },
+ { "CSMSG_SET_PUBCMD", "pubcmd", 0, 5, 0, 0 },
+ { "CSMSG_SET_SETTERS", "setters", 400, 7, 0, 0 },
+ { "CSMSG_SET_CTCPUSERS", "ctcpusers", 0, 9, 0, 0 },
+ { "CSMSG_SET_USERINFO", "userinfo", 1, ~0, CHANNEL_INFO_LINES, 1 },
+ { "CSMSG_SET_INVITEME", "inviteme", 1, ~0, CHANNEL_PEON_INVITE, 200 },
+ { "CSMSG_SET_TOPICSNARF", "topicsnarf", 501, ~0, CHANNEL_TOPIC_SNARF, 1 }
};
struct charOptionValues {
user is optional, if not null, it skips checking that userNode
(for the handle_part function) */
static void
-scan_handle_presence(struct chanNode *channel, struct handle_info *handle, struct userNode *user)
+scan_user_presence(struct userData *uData, struct userNode *user)
{
- struct userData *uData;
-
- if(!channel->channel_info || IsSuspended(channel->channel_info))
- return;
+ struct modeNode *mn;
- uData = GetTrueChannelAccess(channel->channel_info, handle);
- if(uData)
+ if(IsSuspended(uData->channel)
+ || IsUserSuspended(uData)
+ || !(mn = find_handle_in_channel(uData->channel->channel, uData->handle, user)))
{
- struct modeNode *mn = find_handle_in_channel(channel, handle, user);
-
- if(mn)
- {
- uData->present = 1;
- uData->seen = now;
- }
- else
- uData->present = 0;
+ uData->present = 0;
+ }
+ else
+ {
+ uData->present = 1;
+ uData->seen = now;
}
}
channel = AddChannel(argv[1], now, NULL, NULL);
cData = register_channel(channel, user->handle_info->handle);
- add_channel_user(cData, handle, UL_OWNER, 0, NULL);
- scan_handle_presence(channel, handle, NULL);
+ scan_user_presence(add_channel_user(cData, handle, UL_OWNER, 0, NULL), NULL);
cData->modes = chanserv_conf.default_modes;
change = mod_chanmode_dup(&cData->modes, 1);
change->args[change->argc].mode = MODE_CHANOP;
if(!(target = GetChannel(argv[1])))
{
target = AddChannel(argv[1], now, NULL, NULL);
- LockChannel(target);
if(!IsSuspended(channel->channel_info))
AddChannelUser(chanserv, target);
}
DelChannelUser(chanserv, channel, reason2, 0);
}
UnlockChannel(channel);
+ LockChannel(target);
global_message(MESSAGE_RECIPIENT_OPERS | MESSAGE_RECIPIENT_HELPERS, reason);
return 1;
}
return 0;
}
- access = user_level_from_name(argv[1], UL_OWNER);
+ access = user_level_from_name(argv[2], UL_OWNER);
if(!access)
{
- reply("CSMSG_INVALID_ACCESS", argv[1]);
+ reply("CSMSG_INVALID_ACCESS", argv[2]);
return 0;
}
return 0;
}
- if(!(handle = modcmd_get_handle_info(user, argv[2])))
+ if(!(handle = modcmd_get_handle_info(user, argv[1])))
return 0;
if((actee = GetTrueChannelAccess(channel->channel_info, handle)))
}
actee = add_channel_user(channel->channel_info, handle, access, 0, NULL);
- scan_handle_presence(channel, handle, NULL);
+ scan_user_presence(actee, NULL);
reply("CSMSG_ADDED_USER", handle->handle, channel->name, access);
return 1;
}
continue;
if(((uData->access >= min_access) && (uData->access <= max_access))
- || (max_access && (uData->access < actor->access)))
+ || (!max_access && (uData->access < actor->access)))
{
del_channel_user(uData, 1);
count++;
}
}
+ if(!max_access)
+ {
+ min_access = 1;
+ max_access = UL_OWNER;
+ }
send_message(user, chanserv, "CSMSG_TRIMMED_USERS", count, min_access, max_access, channel->name, intervalString(interval, duration));
return 1;
}
free(bData->reason);
bData->reason = strdup(reason);
safestrncpy(bData->owner, (user->handle_info ? user->handle_info->handle : user->nick), sizeof(bData->owner));
- reply("CSMSG_REASON_CHANGE", ban);
+ if(cmd)
+ reply("CSMSG_REASON_CHANGE", ban);
if(!bData->expires)
goto post_add_ban;
}
if(bData->expires)
timeq_add(bData->expires, expire_ban, bData);
- if(duration)
+ if(!cmd)
+ {
+ /* automated kickban */
+ }
+ else if(duration)
reply("CSMSG_BAN_EXTENDED", ban, intervalString(interval, duration));
else
reply("CSMSG_BAN_ADDED", name, channel->name);
goto post_add_ban;
}
}
- reply("CSMSG_REDUNDANT_BAN", name, channel->name);
+ if(cmd)
+ reply("CSMSG_REDUNDANT_BAN", name, channel->name);
free(ban);
return 0;
if(channel->banlist.used >= MAXBANS)
{
- reply("CSMSG_BANLIST_FULL", channel->name);
+ if(cmd)
+ reply("CSMSG_BANLIST_FULL", channel->name);
free(ban);
return 0;
}
change->args[n++].hostmask = ban;
}
change->argc = n;
- if (cmd)
+ if(cmd)
modcmd_chanmode_announce(change);
else
mod_chanmode_announce(chanserv, channel, change);
if(exists && (action == ACTION_BAN))
{
- reply("CSMSG_REDUNDANT_BAN", name, channel->name);
+ if(cmd)
+ reply("CSMSG_REDUNDANT_BAN", name, channel->name);
free(ban);
return 0;
}
return 1;
}
-static CHANSERV_FUNC(cmd_access)
+static CHANSERV_FUNC(cmd_myaccess)
{
- struct userNode *target;
struct handle_info *target_handle;
struct userData *uData;
- int helping;
- char prefix[MAXLEN];
+ const char *chanName;
- if(!channel)
+ if(argc < 2)
+ target_handle = user->handle_info;
+ else if(!IsHelping(user))
{
- struct userData *uData;
- const char *chanName;
- int hide = 0;
+ reply("CSMSG_MYACCESS_SELF_ONLY", argv[0]);
+ return 0;
+ }
+ else if(!(target_handle = modcmd_get_handle_info(user, argv[1])))
+ return 0;
- target_handle = user->handle_info;
- if(!target_handle)
- {
- reply("MSG_AUTHENTICATE");
- return 0;
- }
- if(argc > 1)
- {
- if(!IsHelping(user))
- {
- reply("CSMSG_ACCESS_SELF_ONLY", argv[0]);
- return 0;
- }
+ if(!target_handle->channels)
+ {
+ reply("CSMSG_SQUAT_ACCESS", target_handle->handle);
+ return 1;
+ }
- if(!(target_handle = modcmd_get_handle_info(user, argv[1])))
- return 0;
- hide = 1;
- }
- if(!target_handle->channels)
- {
- reply("CSMSG_SQUAT_ACCESS");
- return 1;
- }
- reply("CSMSG_INFOLINE_LIST", target_handle->handle);
- for(uData = target_handle->channels; uData; uData = uData->u_next)
- {
- struct chanData *cData = uData->channel;
+ reply("CSMSG_INFOLINE_LIST", target_handle->handle);
+ for(uData = target_handle->channels; uData; uData = uData->u_next)
+ {
+ struct chanData *cData = uData->channel;
- if(uData->access > UL_OWNER)
- continue;
- if(IsProtected(cData) && hide && !GetTrueChannelAccess(cData, user->handle_info))
- continue;
- chanName = cData->channel->name;
- if(uData->info)
- send_message_type(4, user, cmd->parent->bot, "[%s (%d)] %s", chanName, uData->access, uData->info);
- else
- send_message_type(4, user, cmd->parent->bot, "[%s (%d)]", chanName, uData->access);
- }
- return 1;
+ if(uData->access > UL_OWNER)
+ continue;
+ if(IsProtected(cData)
+ && (target_handle != user->handle_info)
+ && !GetTrueChannelAccess(cData, user->handle_info))
+ continue;
+ chanName = cData->channel->name;
+ if(uData->info)
+ send_message_type(4, user, cmd->parent->bot, "[%s (%d)] %s", chanName, uData->access, uData->info);
+ else
+ send_message_type(4, user, cmd->parent->bot, "[%s (%d)]", chanName, uData->access);
}
+ return 1;
+}
+
+static CHANSERV_FUNC(cmd_access)
+{
+ struct userNode *target;
+ struct handle_info *target_handle;
+ struct userData *uData;
+ int helping;
+ char prefix[MAXLEN];
+
if(argc < 2)
{
target = user;
tmp_table.flags = list->table.flags;
list->table.contents[0][0] = " ";
highest = list->highest;
- if (list->lowest != 0)
+ if(list->lowest != 0)
lowest = list->lowest;
- else if (highest < 100)
+ else if(highest < 100)
lowest = 1;
else
lowest = highest - 100;
else
SetChannelTopic(channel, chanserv, topic, 1);
- if(cData->flags & CHANNEL_TOPIC_SNARF)
+ if(check_user_level(channel, user, lvlTopicSnarf, 1, 0))
{
/* Grab the topic and save it as the default topic. */
free(cData->topic);
static CHANSERV_FUNC(cmd_inviteme)
{
- struct userData *uData;
-
if(GetUserMode(channel, user))
{
reply("CSMSG_YOU_ALREADY_PRESENT", channel->name);
return 0;
}
if(channel->channel_info
- && !(channel->channel_info->flags & CHANNEL_PEON_INVITE)
- && (uData = GetChannelUser(channel->channel_info, user->handle_info))
- && (uData->access < channel->channel_info->lvlOpts[lvlGiveOps]))
+ && !check_user_level(channel, user, lvlInviteMe, 1, 0))
{
reply("CSMSG_LOW_CHANNEL_ACCESS", channel->name);
return 0;
case NOTE_SET_CHANNEL_SETTER:
return check_user_level(channel, user, lvlSetters, 1, 0);
case NOTE_SET_PRIVILEGED: default:
- return IsHelping(user);
+ return IsHelping(user) && (user->handle_info->opserv_level >= ntype->set_access.min_opserv);
}
}
CHANNEL_BINARY_OPTION("CSMSG_SET_NODELETE", CHANNEL_NODELETE);
}
+static MODCMD_FUNC(chan_opt_dynlimit)
+{
+ CHANNEL_BINARY_OPTION("CSMSG_SET_DYNLIMIT", CHANNEL_DYNAMIC_LIMIT);
+}
+
+/* TODO: reimplement
+
static MODCMD_FUNC(chan_opt_userinfo)
{
CHANNEL_BINARY_OPTION("CSMSG_SET_USERINFO", CHANNEL_INFO_LINES);
CHANNEL_BINARY_OPTION("CSMSG_SET_VOICE", CHANNEL_VOICE_ALL);
}
-static MODCMD_FUNC(chan_opt_dynlimit)
-{
- CHANNEL_BINARY_OPTION("CSMSG_SET_DYNLIMIT", CHANNEL_DYNAMIC_LIMIT);
-}
-
static MODCMD_FUNC(chan_opt_topicsnarf)
{
if((argc > 0) && !check_user_level(channel, user, lvlEnfTopic, 1, 0))
CHANNEL_BINARY_OPTION("CSMSG_SET_PEONINVITE", CHANNEL_PEON_INVITE);
}
+*/
+
static MODCMD_FUNC(chan_opt_defaults)
{
struct userData *uData;
return 0;
}
value = user_level_from_name(argv[1], UL_OWNER+1);
- if(!value && !isdigit(argv[1][0]))
+ if(!value && strcmp(argv[1], "0"))
{
reply("CSMSG_INVALID_ACCESS", argv[1]);
return 0;
}
uData = GetChannelUser(cData, user->handle_info);
- if(!uData || (uData->access < value))
+ if(!uData || ((uData->access < UL_OWNER) && (value > uData->access)))
{
reply("CSMSG_BAD_SETLEVEL");
return 0;
}
+ switch(option)
+ {
+ case lvlGiveVoice:
+ if(value > cData->lvlOpts[lvlGiveOps])
+ {
+ reply("CSMSG_BAD_GIVEVOICE", cData->lvlOpts[lvlGiveOps]);
+ return 0;
+ }
+ break;
+ case lvlGiveOps:
+ if(value < cData->lvlOpts[lvlGiveVoice])
+ {
+ reply("CSMSG_BAD_GIVEOPS", cData->lvlOpts[lvlGiveVoice]);
+ return 0;
+ }
+ break;
+ case lvlSetters:
+ /* This test only applies to owners, since non-owners
+ * trying to set an option to above their level get caught
+ * by the CSMSG_BAD_SETLEVEL test above.
+ */
+ if(value > uData->access)
+ {
+ reply("CSMSG_BAD_SETTERS");
+ return 0;
+ }
+ break;
+ default:
+ break;
+ }
cData->lvlOpts[option] = value;
}
reply(levelOptions[option].format_name, cData->lvlOpts[option]);
return channel_level_option(lvlCTCPUsers, CSFUNC_ARGS);
}
+static MODCMD_FUNC(chan_opt_userinfo)
+{
+ return channel_level_option(lvlUserInfo, CSFUNC_ARGS);
+}
+
+static MODCMD_FUNC(chan_opt_givevoice)
+{
+ return channel_level_option(lvlGiveVoice, CSFUNC_ARGS);
+}
+
+static MODCMD_FUNC(chan_opt_topicsnarf)
+{
+ return channel_level_option(lvlTopicSnarf, CSFUNC_ARGS);
+}
+
+static MODCMD_FUNC(chan_opt_inviteme)
+{
+ return channel_level_option(lvlInviteMe, CSFUNC_ARGS);
+}
+
static int
channel_multiple_option(enum charOption option, struct userNode *user, struct chanNode *channel, int argc, char *argv[], struct svccmd *cmd)
{
}
owner = curr_user;
}
+ curr_user = owner;
}
if(!(new_owner_hi = modcmd_get_handle_info(user, argv[1])))
return 0;
const char *fmt;
REQUIRE_PARAMS(2);
- if((count = strtoul(argv[1], &sep, 10)) <= 1)
+ if((count = strtoul(argv[1], &sep, 10)) < 1)
goto no_dice;
if(sep[0] == 0)
{
+ if(count == 1)
+ goto no_dice;
sides = count;
count = 1;
modifier = 0;
sprintf(response, fmt, total, sides);
}
if(channel)
- send_target_message(5, channel->name, cmd->parent->bot, "$b%s$b: %s", user->nick, response);
+ send_channel_message(channel, cmd->parent->bot, "$b%s$b: %s", user->nick, response);
else
send_message_type(4, user, cmd->parent->bot, "%s", response);
return 1;
timeq_add(now + chanserv_conf.adjust_delay, chanserv_adjust_limit, cData);
}
- if(cData->lvlOpts[lvlGiveOps] == 0)
+ if(channel->join_flooded)
+ {
+ /* don't automatically give ops or voice during a join flood */
+ }
+ else if(cData->lvlOpts[lvlGiveOps] == 0)
modes |= MODE_CHANOP;
- else if((cData->flags & CHANNEL_VOICE_ALL) && !channel->join_flooded)
+ else if(cData->lvlOpts[lvlGiveVoice] == 0)
modes |= MODE_VOICE;
greeting = cData->greeting;
/* Ops and above were handled by the above case. */
if(IsUserAutoOp(uData))
{
- if(uData->access < cData->lvlOpts[lvlGiveOps])
- modes |= MODE_VOICE;
- else
+ if(uData->access >= cData->lvlOpts[lvlGiveOps])
modes |= MODE_CHANOP;
+ else if(uData->access >= cData->lvlOpts[lvlGiveVoice])
+ modes |= MODE_VOICE;
}
if(uData->access >= UL_PRESENT)
cData->visited = now;
-
- uData->seen = now;
- uData->present = 1;
-
if(cData->user_greeting)
greeting = cData->user_greeting;
if(uData->info
- && (cData->flags & CHANNEL_INFO_LINES)
+ && (uData->access >= cData->lvlOpts[lvlUserInfo])
&& ((now - uData->seen) >= chanserv_conf.info_delay)
&& !uData->present)
info = 1;
+ uData->seen = now;
+ uData->present = 1;
}
}
if(!user->uplink->burst)
{
if(modes)
{
+ if(modes & MODE_CHANOP)
+ modes &= ~MODE_VOICE;
change.args[0].mode = modes;
change.args[0].member = mNode;
mod_chanmode_announce(chanserv, channel, &change);
if(greeting && !user->uplink->burst)
send_message_type(4, user, chanserv, "(%s) %s", channel->name, greeting);
if(uData && info)
- send_target_message(4, channel->name, chanserv, "[%s] %s", user->nick, uData->info);
+ send_target_message(5, channel->name, chanserv, "[%s] %s", user->nick, uData->info);
}
return 0;
}
{
struct chanNode *cn;
struct modeNode *mn;
- if(IsSuspended(channel->channel) || !(cn = channel->channel->channel))
+ if(IsUserSuspended(channel)
+ || IsSuspended(channel->channel)
+ || !(cn = channel->channel->channel))
continue;
mn = GetUserMode(cn, user);
{
if(!IsUserSuspended(channel)
&& IsUserAutoInvite(channel)
+ && (channel->access >= channel->channel->lvlOpts[lvlInviteMe])
&& (cn->modes & (MODE_KEY | MODE_INVITEONLY))
&& !self->burst)
irc_invite(chanserv, user, cn);
{
if(channel->access >= cn->channel_info->lvlOpts[lvlGiveOps])
change.args[0].mode = MODE_CHANOP;
- else
+ else if(channel->access >= cn->channel_info->lvlOpts[lvlGiveVoice])
change.args[0].mode = MODE_VOICE;
+ else
+ change.args[0].mode = 0;
change.args[0].member = mn;
- mod_chanmode_announce(chanserv, cn, &change);
+ if(change.args[0].mode)
+ mod_chanmode_announce(chanserv, cn, &change);
}
channel->seen = now;
{
struct chanData *cData;
struct userData *uData;
- struct handle_info *handle;
cData = channel->channel_info;
- if(!cData || IsSuspended(cData) || IsLocal(user)) return;
+ if(!cData || IsSuspended(cData) || IsLocal(user))
+ return;
if((cData->flags & CHANNEL_DYNAMIC_LIMIT) && !channel->join_flooded)
{
}
}
- if((handle = user->handle_info) && (uData = GetTrueChannelAccess(cData, handle)))
- {
- uData->seen = now;
- scan_handle_presence(channel, handle, user);
- }
+ if((uData = GetTrueChannelAccess(cData, user->handle_info)))
+ scan_user_presence(uData, user);
if(IsHelping(user) && IsSupportHelper(user))
{
static void
handle_kick(struct userNode *kicker, struct userNode *victim, struct chanNode *channel)
{
- char *reason = "CSMSG_USER_PROTECTED";
-
if(!channel->channel_info || !kicker || IsService(kicker)
|| (kicker == victim) || IsSuspended(channel->channel_info)
|| (kicker->handle_info && kicker->handle_info == victim->handle_info))
return;
if(protect_user(victim, kicker, channel->channel_info))
+ {
+ const char *reason = user_find_message(kicker, "CSMSG_USER_PROTECTED");
KickChannelUser(kicker, channel, chanserv, reason);
+ }
}
static int
{
struct chanData *cData;
- if(!channel->channel_info || !user || IsSuspended(channel->channel_info) || IsService(user)) return 0;
+ if(!channel->channel_info || !user || IsSuspended(channel->channel_info) || IsService(user))
+ return 0;
cData = channel->channel_info;
if(bad_topic(channel, user, channel->topic))
return 1;
}
/* With topicsnarf, grab the topic and save it as the default topic. */
- if(cData->flags & CHANNEL_TOPIC_SNARF)
+ if(check_user_level(channel, user, lvlTopicSnarf, 0, 0))
{
free(cData->topic);
cData->topic = strdup(channel->topic);
bounce->args[bnc].member = GetUserMode(channel, user);
if(bounce->args[bnc].member)
bnc++;
+ deopped = 1;
}
bounce->args[bnc].mode = MODE_CHANOP;
bounce->args[bnc].member = change->args[ii].member;
bounce->args[bnc].mode = MODE_REMOVE | MODE_BAN;
bounce->args[bnc].hostmask = ban;
bnc++;
- send_message(user, chanserv, "CSMSG_MASK_PROTECTED", remove);
+ send_message(user, chanserv, "CSMSG_MASK_PROTECTED", ban);
}
}
if(bounce)
{
- if((bounce->argc = bnc))
+ if((bounce->argc = bnc) || bounce->modes_set || bounce->modes_clear)
mod_chanmode_announce(chanserv, channel, bounce);
mod_chanmode_free(bounce);
}
else
{
static const char *list[] = {
- /* multiple choice options */
+ /* free form text */
"DefaultTopic", "TopicMask", "Greeting", "UserGreeting", "Modes",
- "PubCmd", "GiveOps", "EnfOps", "EnfModes", "EnfTopic", "Protect",
- "Toys", "Setters", "TopicRefresh", "CtcpUsers", "CtcpReaction",
+ /* options based on user level */
+ "PubCmd", "InviteMe", "UserInfo", "GiveVoice", "GiveOps", "EnfOps",
+ "EnfModes", "EnfTopic", "TopicSnarf", "Setters", "CtcpUsers",
+ /* multiple choice options */
+ "CtcpReaction", "Protect", "Toys", "TopicRefresh",
/* binary options */
- "Voice", "UserInfo", "DynLimit", "TopicSnarf", "PeonInvite", "NoDelete",
+ "DynLimit", "NoDelete",
/* delimiter */
- NULL };
+ NULL
+ };
unsigned int ii;
strlist = alloc_string_list(ArrayLength(list)-1);
for(ii=0; list[ii]; ii++)
chanserv_conf.eightball = strlist;
free_string_list(chanserv_conf.old_ban_names);
strlist = database_get_data(conf_node, KEY_OLD_BAN_NAMES, RECDB_STRING_LIST);
- if (strlist)
+ if(strlist)
strlist = string_list_copy(strlist);
else
strlist = alloc_string_list(2);
{
enum levelOption lvlOpt;
enum charOption chOpt;
+
+ if((str = database_get_data(obj, KEY_FLAGS, RECDB_QSTRING)))
+ cData->flags = atoi(str);
+
for(lvlOpt = 0; lvlOpt < NUM_LEVEL_OPTIONS; ++lvlOpt)
{
- if(!(str = database_get_data(obj, levelOptions[lvlOpt].db_name, RECDB_QSTRING)))
- continue;
- cData->lvlOpts[lvlOpt] = user_level_from_name(str, UL_OWNER+1);
+ str = database_get_data(obj, levelOptions[lvlOpt].db_name, RECDB_QSTRING);
+ if(str)
+ cData->lvlOpts[lvlOpt] = user_level_from_name(str, UL_OWNER+1);
+ else if(levelOptions[lvlOpt].old_flag)
+ {
+ if(cData->flags & levelOptions[lvlOpt].old_flag)
+ cData->lvlOpts[lvlOpt] = levelOptions[lvlOpt].flag_value;
+ else
+ cData->lvlOpts[lvlOpt] = levelOptions[lvlOpt].default_value;
+ }
}
+
for(chOpt = 0; chOpt < NUM_CHAR_OPTIONS; ++chOpt)
{
if(!(str = database_get_data(obj, charOptions[chOpt].db_name, RECDB_QSTRING)))
continue;
cData->chOpts[chOpt] = str[0];
}
- if((str = database_get_data(channel, KEY_FLAGS, RECDB_QSTRING)))
- cData->flags = atoi(str);
}
else if((str = database_get_data(channel, KEY_FLAGS, RECDB_QSTRING)))
{
for(lvlOpt = 0; lvlOpt < NUM_LEVEL_OPTIONS; ++lvlOpt)
{
unsigned short lvl;
- switch(((count <= levelOptions[lvlOpt].old_idx) ? str : CHANNEL_DEFAULT_OPTIONS)[levelOptions[lvlOpt].old_idx])
+ if(levelOptions[lvlOpt].old_flag)
+ {
+ if(cData->flags & levelOptions[lvlOpt].old_flag)
+ lvl = levelOptions[lvlOpt].flag_value;
+ else
+ lvl = levelOptions[lvlOpt].default_value;
+ }
+ else switch(((count <= levelOptions[lvlOpt].old_idx) ? str : CHANNEL_DEFAULT_OPTIONS)[levelOptions[lvlOpt].old_idx])
{
case 'c': lvl = UL_COOWNER; break;
case 'm': lvl = UL_MASTER; break;
cData->flags &= ~CHANNEL_SUSPENDED;
}
- if((cData->flags & CHANNEL_SUSPENDED) && (suspended->expires > now))
- {
- timeq_add(suspended->expires, chanserv_expire_suspension, suspended);
- }
- else
+ if(!(cData->flags & CHANNEL_SUSPENDED))
{
struct mod_chanmode change;
change.modes_set = change.modes_clear = 0;
change.args[0].member = AddChannelUser(chanserv, cNode);
mod_chanmode_announce(chanserv, cNode, &change);
}
+ else if(suspended->expires > now)
+ {
+ timeq_add(suspended->expires, chanserv_expire_suspension, suspended);
+ }
str = database_get_data(channel, KEY_REGISTERED, RECDB_QSTRING);
cData->registered = str ? (time_t)strtoul(str, NULL, 0) : now;
DEFINE_COMMAND(mdelpeon, 2, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
DEFINE_COMMAND(trim, 3, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
- DEFINE_COMMAND(opchan, 1, MODCMD_REQUIRE_REGCHAN, "access", "peon", NULL);
+ DEFINE_COMMAND(opchan, 1, MODCMD_REQUIRE_REGCHAN, "access", "1", NULL);
DEFINE_COMMAND(clvl, 3, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
DEFINE_COMMAND(giveownership, 2, MODCMD_REQUIRE_CHANUSER, "access", "owner", "flags", "+loghostmask", NULL);
DEFINE_COMMAND(open, 1, MODCMD_REQUIRE_CHANUSER, "template", "op", NULL);
DEFINE_COMMAND(topic, 1, MODCMD_REQUIRE_REGCHAN, "template", "op", "flags", "+never_csuspend", NULL);
DEFINE_COMMAND(mode, 1, MODCMD_REQUIRE_REGCHAN, "template", "op", NULL);
- DEFINE_COMMAND(inviteme, 1, MODCMD_REQUIRE_CHANNEL, "access", "peon", NULL);
+ DEFINE_COMMAND(inviteme, 1, MODCMD_REQUIRE_CHANNEL, "access", "1", NULL);
DEFINE_COMMAND(invite, 1, MODCMD_REQUIRE_CHANNEL, "access", "master", NULL);
DEFINE_COMMAND(set, 1, MODCMD_REQUIRE_CHANUSER, "access", "op", NULL);
DEFINE_COMMAND(wipeinfo, 2, MODCMD_REQUIRE_CHANUSER, "access", "master", NULL);
DEFINE_COMMAND(addban, 2, MODCMD_REQUIRE_REGCHAN, "access", "250", NULL);
DEFINE_COMMAND(addtimedban, 3, MODCMD_REQUIRE_REGCHAN, "access", "250", NULL);
DEFINE_COMMAND(delban, 2, MODCMD_REQUIRE_REGCHAN, "access", "250", NULL);
- DEFINE_COMMAND(uset, 1, MODCMD_REQUIRE_CHANUSER, "access", "peon", NULL);
+ DEFINE_COMMAND(uset, 1, MODCMD_REQUIRE_CHANUSER, "access", "1", NULL);
- DEFINE_COMMAND(bans, 1, MODCMD_REQUIRE_REGCHAN, "access", "peon", "flags", "+nolog", NULL);
+ DEFINE_COMMAND(bans, 1, MODCMD_REQUIRE_REGCHAN, "access", "1", "flags", "+nolog", NULL);
DEFINE_COMMAND(peek, 1, MODCMD_REQUIRE_REGCHAN, "access", "op", "flags", "+nolog", NULL);
- DEFINE_COMMAND(access, 1, 0, "flags", "+nolog,+acceptchan", NULL);
+ DEFINE_COMMAND(myaccess, 1, MODCMD_REQUIRE_AUTHED, NULL);
+ DEFINE_COMMAND(access, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(users, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(wlist, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_COMMAND(clist, 1, MODCMD_REQUIRE_REGCHAN, "flags", "+nolog,+joinable", NULL);
DEFINE_CHANNEL_OPTION(enfmodes);
DEFINE_CHANNEL_OPTION(enftopic);
DEFINE_CHANNEL_OPTION(pubcmd);
- DEFINE_CHANNEL_OPTION(voice);
+ DEFINE_CHANNEL_OPTION(givevoice);
DEFINE_CHANNEL_OPTION(userinfo);
DEFINE_CHANNEL_OPTION(dynlimit);
DEFINE_CHANNEL_OPTION(topicsnarf);
DEFINE_CHANNEL_OPTION(topicrefresh);
DEFINE_CHANNEL_OPTION(ctcpusers);
DEFINE_CHANNEL_OPTION(ctcpreaction);
- DEFINE_CHANNEL_OPTION(peoninvite);
+ DEFINE_CHANNEL_OPTION(inviteme);
modcmd_register(chanserv_module, "set defaults", chan_opt_defaults, 1, 0, "access", "owner", NULL);
/* Alias set topic to set defaulttopic for compatibility. */