Added forcekick command to opserv to allow kicking of +k opers.
[srvx.git] / src / opserv.c
index 3945216f94fa42bf671d2c096532a7ba27610afa..8a5f2a53fcf034130be5f90f1d5a85a0355e2cf5 100644 (file)
@@ -252,6 +252,7 @@ static const struct message_entry msgtab[] = {
     { "OSMSG_CHANINFO_USER_COUNT", "Users (%d):" },
     { "OSMSG_CSEARCH_CHANNEL_INFO", "%s [%d users] %s %s" },
     { "OSMSG_TRACE_MAX_CHANNELS", "You may not use the 'channel' criterion more than %d times." },
+    { "OSMSG_FORCEKICK_LOCAL", "You cannot kick $b%s$b forcefully." },
     { NULL, NULL }
 };
 
@@ -807,7 +808,7 @@ static MODCMD_FUNC(cmd_block)
         offset = 3;
     }
     if(duration && duration != opserv_conf.block_gline_duration) {
-        // We require more access when the duration is not the default block duration.
+        /* We require more access when the duration is not the default block duration. */
         gline_cmd = dict_find(cmd->parent->commands, "gline", NULL);
         if(!gline_cmd)
         {
@@ -1006,6 +1007,34 @@ static MODCMD_FUNC(cmd_kick)
     return 1;
 }
 
+static MODCMD_FUNC(cmd_forcekick)
+{
+    struct userNode *target;
+    char *reason;
+
+    if (argc < 3) {
+        reason = alloca(strlen(OSMSG_KICK_REQUESTED)+strlen(user->nick)+1);
+        sprintf(reason, OSMSG_KICK_REQUESTED, user->nick);
+    } else {
+        reason = unsplit_string(argv+2, argc-2, NULL);
+    }
+    target = GetUserH(argv[1]);
+    if (!target) {
+        reply("MSG_NICK_UNKNOWN", argv[1]);
+        return 0;
+    }
+    if (!GetUserMode(channel, target)) {
+        reply("OSMSG_NOT_ON_CHANNEL", target->nick, channel->name);
+        return 0;
+    }
+    if (IsLocal(target)) {
+        reply("OSMSG_FORCEKICK_LOCAL", target->nick);
+        return 0;
+    }
+    irc_kick(cmd->parent->bot, target, channel, reason);
+    return 1;
+}
+
 static MODCMD_FUNC(cmd_kickall)
 {
     unsigned int limit, n, inchan;
@@ -3318,7 +3347,7 @@ is_oper_victim(struct userNode *user, struct userNode *target, int match_opers,
                   || (target->handle_info
                       && target->handle_info->opserv_level > user->handle_info->opserv_level));
 
-    // If we don't need an ip check or want to hit opers or the the "cheap" check already disqualified the target, we are done.
+    /* If we don't need an ip check or want to hit opers or the the "cheap" check already disqualified the target, we are done. */
     if (!check_ip || match_opers || !is_victim)
         return is_victim;
 
@@ -4267,6 +4296,7 @@ init_opserv(const char *nick)
     opserv_define_func("JUMP", cmd_jump, 900, 0, 2);
     opserv_define_func("JUPE", cmd_jupe, 900, 0, 4);
     opserv_define_func("KICK", cmd_kick, 100, 2, 2);
+    opserv_define_func("FORCEKICK", cmd_forcekick, 800, 2, 2);
     opserv_define_func("KICKALL", cmd_kickall, 400, 2, 0);
     opserv_define_func("KICKBAN", cmd_kickban, 100, 2, 2);
     opserv_define_func("KICKBANALL", cmd_kickbanall, 450, 2, 0);