summaryrefslogblamecommitdiff
path: root/npc/functions/captcha.txt
blob: 7fce7ff70d94cca6b3019c45211206a9f39dc14d (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12











                                                                         
                                                                           

                            
                                       
                                                                         
                                   
                                 
                                             































                                           
                            































                                                                             
                                                                            











                                                                          


                               












                                                                     
                                               




                                            






                                                                            








                                                                                                                









































                                                                                                                                           
                                                             




























                                                                                           

                                                                                                                       












                                                                                               




                                                             
                                                     


                 








                                        











































                                                                                 


                                   
              
              
              


                 

                                                                          





                                






                                                




                                                      
 
                                      
                                         

                                                       
                                 
                                         

                                                                 




                                      



                                                                          
                                               

                                       
 








                                                           
                                                                                                                                                                




                                        





                                                         
                                                     































                                                                                 

                                                                                   
                                           

                                                              


                                                                                









                                                                               
                                                       



                                                                                 
                                                                             















                                                                    

                                   

                                                                 
                                    

                                                                               
                                    
                                                                    
                                                  



                                                                     
                                                                   
                                 
                                   
                                                                 

                                   
                                                                           
                                    
                                   
                                                                              

                                     
                                                        

                                    
                                                 
                                     

                                                                 
                                                                 
                                   
                                                              

                                                                 
                                                               
                               
                                   
                                                                             

                                  








                                                                            



                                                                      
                                                                                 
                                                                                 

                                                                                    

                                                             












                                                                                  
                                                               
                                                                           
                                  







                                                                             
                                               
                                                                                   

                                                                                                                                                                                   
                 























                                                                                    
                                                                           
                                                   
                                                                                                                                                        





                                  











                                                                                                        





           
// TMW2 functions.
// Author:
//    Jesusalva
// Description:
//    Random CAPTCHA check against AFK robots.
//    TODO: Put this in a blackbox for bots which sniff text chat.
// Variables:
//    gettimetick(2) variables: CAPTCHA_TIME | CAPTCHA_OK
//    CAPTCHA_1 | CAPTCHA_2 | CAPTCHA_ANSWER => The correct captcha reply
//    CAPTCHA_OP$ => The operation, defaults to "+"
//    $@BOTCHECK_TARGET => The account ID of the char being probed
//    @captcha_cooldown => anti-flood
//    CAPTCHA_NPC$ => The Map which the nurse can clear the Botter Syndrome
//    $CAPTCHA (bitmask)
//      0 - Captcha Disabled
//      1 - Captcha Enabled (Banhammer)
//      2 - Display warnings (@captcha_lastwarning/@captcha_lastwarningt)
//      4 - Botter Syndrome enabled
//      8 - Disable during events
//     16 - Allow players to treat each other

// CaptchName, names the number
function	script	CaptchName	{
    switch (getarg(0)) {
        case 0: return l("zero");
        case 1: return l("one");
        case 2: return l("two");
        case 3: return l("three");
        case 4: return l("four");
        case 5: return l("five");
        case 6: return l("six");
        case 7: return l("seven");
        case 8: return l("eight");
        case 9: return l("nine");
        case 10: return l("ten");
        case 11: return l("eleven");
        case 12: return l("twelve");
        case 13: return l("thirteen");
        case 14: return l("fourteen");
        case 15: return l("fifteen");
        case 16: return l("sixteen");
        case 17: return l("seventeen");
        case 18: return l("eighteen");
        case 19: return l("nineteen");
        case 20: return l("twenty");
    }
    return getarg(0);
}

// MakeCaptch, makes a captcha and saves it
function	script	MakeCaptch	{
    CAPTCHA_TIME=gettimetick(2);
    CAPTCHA_OK=CAPTCHA_TIME;
    CAPTCHA_1=rand2(21);
    CAPTCHA_2=rand2(20);
    // select a operation
    switch (rand2(1)) {
        case 0:
            CAPTCHA_OP$="-";
            CAPTCHA_ANSWER=CAPTCHA_1-CAPTCHA_2;
            break;
        default:
            CAPTCHA_OP$="+";
            CAPTCHA_ANSWER=CAPTCHA_1+CAPTCHA_2;
            break;
    }
    return;
}

function	script	CaptchVal	{
    // Make it nice
    .@c$=any(
            CAPTCHA_1+CAPTCHA_OP$+CAPTCHA_2,
            CaptchName(CAPTCHA_1)+CAPTCHA_OP$+CAPTCHA_2,
            CAPTCHA_1+CAPTCHA_OP$+CaptchName(CAPTCHA_2),
            CaptchName(CAPTCHA_1)+CAPTCHA_OP$+CaptchName(CAPTCHA_2),
            CAPTCHA_1+" "+CAPTCHA_OP$+" "+CAPTCHA_2,
            CaptchName(CAPTCHA_1)+" "+CAPTCHA_OP$+" "+CAPTCHA_2,
            CAPTCHA_1+" "+CAPTCHA_OP$+" "+CaptchName(CAPTCHA_2),
            CaptchName(CAPTCHA_1)+" "+CAPTCHA_OP$+" "+CaptchName(CAPTCHA_2));
    return .@c$;
}

function	script	CaptchExample	{
    if (!CAPTCHA_TIME || getarg(0, false)) {
        dispbottom("##1TO REPLY TO CAPTCHAS: @captcha <numeric answer>##1");
        dispbottom l("Example: Give the answer for the following: one+1");
        dispbottom l("Reply: %s", b("@captcha 2"));
        dispbottom b(l("This example will not be shown again."));
    }
    return;
}

-	script	@captcha	32767,{
    function captchaProbe;
    end;

OnCall:
    // Command disabled, ignore
    if (!$CAPTCHA & 1)
        end;
    // Not you, ignore
    if (getcharid(3) != $@BOTCHECK_TARGET)
        end;
    // Attempt cooldown
    if (@captcha_cooldown > gettimetick(2)) {
        dispbottom l("CAPTCHA: Cooldown in effect."); end;}
    // Process answer
    @captcha_cooldown=gettimetick(2)+.antiflood;
    // Lets be reasonable
    if (gettimetick(2)+2 > CAPTCHA_TIME) {
        dispbottom l("CAPTCHA: An error happened, try again."); end;}

    // Verify answer
    .@ans$ = implode(.@atcmd_parameters$, " ");
    .@ans=atoi(.@ans$);
    if (.@ans == CAPTCHA_ANSWER) {
        CAPTCHA_OK=gettimetick(2)+.cooldown;
        $@BOTCHECK_TARGET=0;
        dispbottom any(
                        l("Captcha successful"),
                        l("Captcha ok"),
                        l("Correct"),
                        l("Understood"),
                        l("Not bad"),
                        l("Hmpf. That'll do."),
                        l("A bit longer and I would have jailed you %%\\ "),
                        l("%%\\ that'll do."),
                        l("%%N"));
        dispbottom l("Remember: Players can also help enforcing no-AFK-bot rule!");
        //dispbottom l("Remember: Never lend your toothbrush to a slime!");
    } else {
        dispbottom l("CAPTCHA: Incorrect answer. Wait %ds and try again.", .antiflood); // Max 10 attempts total
    }
    end;

OnClinic:
    // Syndrome disabled, ignore
    if (!$CAPTCHA & 4)
        end;
    // Command disabled, ignore
    if (!$CAPTCHA & 16)
        end;
    // You haven't learned how to treat anyone
    if (getq(General_Narrator) < 1 && !getq(CandorQuest_Nurse))
        end;
    // You cannot treat anyone
    if (array_find($CAPTCHA_BLIST, getcharid(3)) >= 0)
        end;
    // Verify the target
    .@request$ = "";
	.@request$ += implode(.@atcmd_parameters$, " ");
    // TODO: Quest - Treat a NPC with Botter's Syndrome (Trainer?)
    // Player is not attached or is yourself
    .@id = getcharid(3, .@request$);
    if (!.@id) {
        Exception("Player not found.", RB_ISFATAL|RB_DISPBOTTOM);
    } else if (.@id == getcharid(3)) {
        Exception("You cannot treat yourself.", RB_ISFATAL|RB_DISPBOTTOM);
    }
    // You already treated someone recently
    if (CHAREG_CLEANUP+300 > gettimetick(2))
        Exception(sprintf("You need to be online for longer than %d minute(s) to treat someone.", 5), RB_ISFATAL|RB_DISPBOTTOM);
    if (@treatcaptcha+300 > gettimetick(2))
        Exception(sprintf("You need to wait %s before treat someone else again.", FuzzyTime(@treatcaptcha+300)), RB_ISFATAL|RB_DISPBOTTOM);
    // Treatment confirmation
    mes ".:: " + l("Treatment") + " ::.";
    mes l("Botter Syndrome is a common ailment which, while it mostly affect bots, even regular adventurers and NPCs may contract.");
    mes l("If you believe \"%s\" is ##Bnot##b botting, then you may treat them yourself.");
    mes "";
    mes l("- Treating a nearby player will almost always succeed.");
    mes l("- Treating a player in the same map has <70%% chance of succeeding.");
    mes l("- Treating a player in another map has <30%% chance of succeeding.");
    mes l("- Treating a bot may result in the Alliance confiscating your treatment kit.");
    mes l("- Treating yourself via an alt may also result in a %s for one of your accounts.", b(l("permanent ban")));
    mes "";
    mes l("It takes %d minute(s) to treat someone else after this.", 5);
    next;
    mesc l("Do you want to treat \"%s\"?", b(.@request$)), 1;
    if (askyesno() == ASK_NO) {
        closeclientdialog;
        end;
    }
    // Regardless of whatever happens now, the treatment was attempted
    .@m1$ = getmap();
    .@caster = getcharid(3);
    .@chance = 30;
    .@benef$ = strcharinfo(0);
    @treatcaptcha = gettimetick(2);
    closeclientdialog;
    // Attach the one you intend to heal
    if (attachplayer(.@id)) {
        // Not infected, so do nothing
        if (!getstatus(SC_BOTTER_SYNDROME))
            end;
        // Same map check
        getmapxy(.@m$, .@x, .@y, 0);
        if (.@m$ == .@m1$) {
            .@chance = 70;
            // Check if caster and treated are visible
            .@c=getunits(BL_PC, .@pcs, MAX_CYCLE_PC, .@m$, .@x-14, .@y-14, .@x+14, .@y+14);
            for (.@i = 0; .@i < .@c; .@i++) {
                if (.@pcs[.@i] == .@caster) {
                    .@chance = 100;
                    break;
                } // Caster loop
            } // for loop
        } // Map loop
        // If we went this far, it is fine to log the result
        logmes sprintf("@treat: \"%s\" treated \"%s\" Botter's Syndrome.", .@benef$, strcharinfo(0)), LOGMES_ATCOMMAND;
        // The chance is further modified by how intense the syndrome is
        // Every 5% effect steals 1% of treatment chance
        .@chance -= limit(0, getstatus(SC_BOTTER_SYNDROME, 1) / 5, 25);
        // Now we have .@chance, so decide if treatment worked
        if (rand2(100) < .@chance) {
            sc_end SC_BOTTER_SYNDROME;
            dispbottom l("Your %s was treated by %s.", b(l("Botter's Syndrome")),.@benef$);
        } else {
            dispbottom l("%s tried to treat your syndrome, but was NOT successful.", .@benef$);
        }
    } // attachplayer()
    end;

OnInit:
    .thr=180; // Seconds to reply
    .cooldown=3600; // Captcha Immunity
    .antiflood=18; // Seconds between captcha failed attempts
    bindatcmd "captcha", "@captcha::OnCall", 0, 0, 0;
    bindatcmd "treat", "@captcha::OnClinic", 0, 0, 0;
    initnpctimer;
    end;

function syndroCheck {
    .@k = getarg(0);
    .@t = getarg(1, 2000);
    sleep2(.@t);
    if (!playerattached()) return false;
    if (BaseExp != .@k) return true;
    return false;
}

// CAPTCHA_NPC$=any("009-4", "024-8", "004-1", "012-6", "005-7", "006-2-1");
//                  Halin    Frost    Tulim    Hurns    Candor   Pious
function syndroNurse {
    if (CAPTCHA_NPC$ != "") return;
    if (LOCATION$ == "Candor" && !compare(getmap(), "005"))
        CAPTCHA_NPC$ = "005-7";
    else if (LOCATION$ == "Candor")
        CAPTCHA_NPC$ = "006-2-1";
    else if (LOCATION$ == "Artis")
        CAPTCHA_NPC$ = "005-7";
    else if (LOCATION$ == "Hurns" && !compare(getmap(), "012"))
        CAPTCHA_NPC$ = "012-6";
    else if (LOCATION$ == "Hurns")
        CAPTCHA_NPC$ = "009-4";
    else if (LOCATION$ == "LoF")
        CAPTCHA_NPC$ = "012-6";
    else if (LOCATION$ == "Lilit")
        CAPTCHA_NPC$ = "012-6";
    else if (LOCATION$ == "Fort")
        CAPTCHA_NPC$ = "012-6";
    else if (LOCATION$ == "Nival" && BaseLevel >= 70)
        CAPTCHA_NPC$ = "024-8";
    else if (LOCATION$ == "Frostia")
        CAPTCHA_NPC$ = "024-8";
    else if (LOCATION$ == "Halin" && !compare(getmap(), "009"))
        CAPTCHA_NPC$ = "009-4";
    else if (LOCATION$ == "Halin" && $HURNS_LIBDATE)
        CAPTCHA_NPC$ = "012-6";
    else if (LOCATION$ == "Halin")
        CAPTCHA_NPC$ = "004-1";
    else if (LOCATION$ == "Tulim" && !compare(getmap(), "004"))
        CAPTCHA_NPC$ = "004-1";
    else if (LOCATION$ == "Tulim" && BaseLevel >= 40)
        CAPTCHA_NPC$ = "009-4";
    // All else failed (several cases where it may), chose one randomly
    else if (BaseLevel >= 70 && $NIVALIS_LIBDATE)
        CAPTCHA_NPC$=any("009-4", "024-8", "004-1", "012-6", "005-7", "006-2-1");
    else if (BaseLevel >= 30 && $HURNS_LIBDATE)
        CAPTCHA_NPC$=any("004-1", "012-6", "005-7", "006-2-1");
    else
        CAPTCHA_NPC$=any("004-1", "005-7");
    return;
}

// Restart if it somehow get struck
OnTimer60000:
OnTimer150000:
OnTimer470000:
OnTimer600000:
OnTimer800000:
    initnpctimer;
    end;

// Pick a random target for captcha checks, which happens every 12 seconds
OnTimer12000:
    // Script disabled by admins
    if (!$CAPTCHA) {
        initnpctimer;
        end;
    }

    // Event in progress and flag to skip is set
    if ($CAPTCHA & 8) {
      if ($@MK_SCENE || $@GM_EVENT) {
        initnpctimer;
        end;
      }
    }

    // If we're using the banhammer, handle the target
    if ($CAPTCHA & 1) {
        if ($@BOTCHECK_TARGET) captchaProbe();
    }

    // Maybe we will conduct a captcha
    if (rand2(28) < 3 || $@GM_OVERRIDE) {
        // This can be slow, beware
        .@c = getunits(BL_PC, .@players, MAX_CYCLE_PC);
        array_shuffle(.@players);
        for (.@i = 0; .@i < .@c; .@i++) {
            // Too lazy to botcheck you today (check chance = 3%)
            if (rand2(100) > 3)
                continue;

            // Okay, lets do it
            attachrid(.@players[.@i]);

            // Inform the GM Override Console about ongoing botcheck
            if ($@GM_OVERRIDE)
                debugmes "[BOT] Conducting botcheck for %d", getcharid(3);

            // TODO: What about jailed players?
            //if (getstatus(SC_JAILED))
            //    continue;

            // 1. Player in immunity, who is next one
            if (CAPTCHA_OK > gettimetick(2)) {
                detachrid();
                continue;
            }

            // 2. Player must be jailed, and we continue
            if (CAPTCHA_TIME < CAPTCHA_OK) {
                atcommand("@jailfor 40mn "+strcharinfo(0));
                dispbottom l("You failed to reply to the captcha in time and were arrested for AFK Botting. You can use @jailtime to keep track of time left.");
                CAPTCHA_OK=CAPTCHA_TIME;
                detachrid();
                continue;
            }

            // 2.1 Player is AFK for more than 30 seconds
            if (checkidle() > 30) {
                detachrid();
                continue;
            }

            // 3. This is a good target, lets do this
            // If banhammer is enabled
            if ($CAPTCHA & 1) {
                .@g$="";
                CaptchExample();
                MakeCaptch();

                .@g$=any(
                        "CAPTCHA: Please reply the following: "+CaptchVal(),
                        "BOTCHECK: Please reply the following: "+CaptchVal(),
                        "CAPTCHA: You must answer this: "+CaptchVal(),
                        "BOTCHECK: You must answer this: "+CaptchVal());

                // 4. Find a random method
                switch (rand2(2)) {
                case 0:
                    message(getcharid(3), .@g$);
                    message(getcharid(3), "Example for one + one: @captcha 2");
                    break;
                case 1:
                    announce(.@g$, bc_self|bc_pc);
                    announce("Example for one + one: @captcha 2", bc_self|bc_pc);
                    break;
                default:
                    dispbottom(.@g$);
                    dispbottom("Example for one + one: @captcha 2");
                    break;
                }
            }

            // 3.1 This is a good target, lets do this
            // If Botter Syndrome is enabled
            if ($CAPTCHA & 4) {
                // Players are exempt of Botting Syndrome until unlocking Tulimshar
                // But if they're deemed overleveled, this exemption dies
                // TODO: Maybe up to Lv 30?
                if (!getq(General_Narrator) && BaseLevel < 15)
                    continue;
                // We will now study you for a short while. First, take a sample
                .@exp = BaseExp; .@jxp = JobExp; .@mpt = Mobpt; .@hp = Hp;
                .@wgt = Weight; .@m$ = getmap(); .@mpk = MONSTERS_KILLED;
                .@hon = HONOR; .@k = BaseExp;
                // We'll now wait in some intervals. Killing in them cause
                // the K variables to be set, and contribute towards bot score.
                .@k1 = syndroCheck(.@k); .@k = BaseExp;
                .@k2 = syndroCheck(.@k); .@k = BaseExp;
                .@k3 = syndroCheck(.@k); .@k = BaseExp;
                .@k4 = syndroCheck(.@k); .@k = BaseExp;
                .@k5 = syndroCheck(.@k); .@k = BaseExp;
                .@k6 = syndroCheck(.@k); .@k = BaseExp;
                .@k7 = syndroCheck(.@k); .@k = BaseExp;
                .@k8 = syndroCheck(.@k); .@k = BaseExp;
                // You logged out? LAME! Anyway, carry on
                if (!playerattached())
                    break;
                /////////////////////////////////////////////////////////////////
                // The chance of you contracting the Syndrome starts at 60.0%
                .@chance = 600;
                // Every 2 seconds you spent without killing is 1.5%
                if (!.@k1)
                    .@chance -= 15;
                if (!.@k2)
                    .@chance -= 15;
                if (!.@k3)
                    .@chance -= 15;
                if (!.@k4)
                    .@chance -= 15;
                if (!.@k5)
                    .@chance -= 15;
                if (!.@k6)
                    .@chance -= 15;
                if (!.@k7)
                    .@chance -= 15;
                if (!.@k8)
                    .@chance -= 15;
                // You killed less than 7 monsters, fall to 40.0%
                if (.@mpk + 7 > MONSTERS_KILLED)
                    .@chance -= 200;
                // (If you killed less than 12 monsters, fall to 55.0% instead)
                else if (.@mpk + 12 > MONSTERS_KILLED)
                    .@chance -= 125;
                // If you interacted with any NPC, it falls to 27.5%
                if (@npctalk+600 > gettimetick(2))
                    .@chance -= 100;
                // You're a light carrier (40% weight), fall to 25.0%
                if (Weight * 4 <= MaxWeight / 10)
                    .@chance -= 30;
                // You assigned all your stat points, fall to 20.0%
                if (!StatusPoint)
                    .@chance -= 25;
                // Monster points did not increase, fall to 17.5%
                if (Mobpt <= .@mpt)
                    .@chance -= 25;
                // Your weight decreased or did not increase, fall to 12.5%
                if (Weight <= .@wgt)
                    .@chance -= 25;
                // Your experience did not increase or level up, fall to 10.0%
                if (BaseExp <= .@exp)
                    .@chance -= 25;
                // Same for job experience, fall to 7.5%
                if (JobExp <= .@jxp)
                    .@chance -= 25;
                // Your map changed, fall to 2.0%
                if (getmap() != .@m$)
                    .@chance -= 55;
                // You are/were in a SuperMMO zone, fall to -0.5%
                if (getmapinfo(MAPINFO_ZONE, .@m$) == "SuperMMO")
                    .@chance -= 30;
                // (If it is a MMO zone, fall to 0.5% instead)
                else if (getmapinfo(MAPINFO_ZONE, .@m$) == "MMO")
                    .@chance -= 15;
                // Your HP increased or remained, fall to -3.0%
                if (Hp >= .@hp)
                    .@chance -= 40;
                // You are staff or sponsor or whatever, total at -3.5% bonus
                if (getgmlevel())
                    .@chance -= 5;
                // You haven't disconnected recently, total at -4.0%
                if (CHAREG_CLEANUP+3600 < gettimetick(2))
                    .@chance -= 5;
                // You already used a skill recently/today, total at -5.0%
                if (@skillId)
                    .@chance -= 10;
                // You killed someone in PVP or died in PVP, total at -10.0%
                if (.@hon != HONOR)
                    .@chance -= 50;
                // You are still a novice, total at -12.0%
                if (!REBIRTH && BaseLevel < 70 && JobLevel < 40)
                    .@chance -= 20;
                // TODO: Total connection time? Item usage? Chat? AOE?
                // TODO: Reduce chance if you've already contracted the Syndrome?
                /////////////////////////////////////////////////////////////////
                if ($@GM_OVERRIDE)
                  debugmes "Botter Syndrome [%s] %d%%", strcharinfo(0), .@chance/10;
                if (rand2(1000) < .@chance) {
                    // You've contracted the Botter Syndrome!
                    // Your rate drop in 1% ~ 15% depending on your botting score
                    .@eff = 1 + (.@chance / 50);
                    // If you already have one running, change effects
                    if (getstatus(SC_BOTTER_SYNDROME)) {
                        .@t = 1 + getstatus(SC_BOTTER_SYNDROME, 5) / 3600000;
                        .@eff += .@t + min(100, getstatus(SC_BOTTER_SYNDROME, 1));
                    }
                    // Sanitize the effect (it can go past 100% but...)
                    .@eff = min(100, .@eff);
                    // The syndrome starts weak and gradually strengthens
                    SC_Bonus(3600, SC_BOTTER_SYNDROME, .@eff);
                    .@t = getstatus(SC_BOTTER_SYNDROME, 5) / 1000;
                    .@eff = limit(0, getstatus(SC_BOTTER_SYNDROME, 1), 100);
                    // Select a nearby Nurse which can cure you
                    // But if your symptoms worsen, keep the previous nurse
                    syndroNurse();
                    // Inform which Nurse can cure you
                    if (CAPTCHA_NPC$ == "009-4")        .@n$=l("Halinarzo");
                    else if (CAPTCHA_NPC$ == "024-8")   .@n$=l("Frostia");
                    else if (CAPTCHA_NPC$ == "004-1")   .@n$=l("Tulimshar");
                    else if (CAPTCHA_NPC$ == "012-6")   .@n$=l("Hurnscald");
                    else if (CAPTCHA_NPC$ == "005-7")   .@n$=l("Candor");
                    else if (CAPTCHA_NPC$ == "006-2-1") .@n$=l("Piou Isles");
                    else .@n$="???";
                    // Send information message
                    dispbottom l("----------------------------------------------");
                    dispbottom l("* You can find a Nurse in %s to heal, wait %s, or drink a %s to dispel.", b(.@n$), FuzzyTime(gettimetick(2)+.@t), getitemlink(ElixirOfLife));
                    dispbottom l("OH NOES! You have contracted the %s! Your experience gain and drop rate was greatly reduced by %d%%!", b(col(l("Botter's Syndrome"), 1)), .@eff);
                }
            }

            // 5. Detach rid, target is set
            $@BOTCHECK_TARGET=getcharid(3);
            detachrid();
            break;
        }
    }

    // Continue this timer forever
    initnpctimer;
    end;

function captchaProbe {
    // Attach rid
    .@online=attachrid($@BOTCHECK_TARGET);

    // User disconnected, next captcha they'll be arrested because timer will expire
    if (!.@online) {
        $@BOTCHECK_TARGET=false;
        CAPTCHA_OK=false;
    }

    // Timer expired? Ban hammer
    if (CAPTCHA_TIME+.thr > gettimetick(2) && CAPTCHA_OK <= CAPTCHA_TIME) {
        atcommand("@jailfor 30mn "+strcharinfo(0));
        dispbottom l("You failed to reply to the captcha in time and were arrested for AFK Botting. You can use @jailtime to keep track of time left.");
        CaptchExample(true);
        $@BOTCHECK_TARGET=false;
        CAPTCHA_OK=CAPTCHA_TIME;
    }

    // Nothing happened, lets wait
    if ($CAPTCHA & 2) {
        if (!@captcha_lastwarningt)
            @captcha_lastwarningt=3;
        if (!@captcha_lastwarning)
            @captcha_lastwarning=gettimetick(2);

        if (@captcha_lastwarning < gettimetick(2)) {
            dispbottom l("CAPTCHA: You have %s minute(s) remaining", CaptchName(@captcha_lastwarningt));
            @captcha_lastwarningt-=1;
            @captcha_lastwarning+=60;
        }
    }
    return;
    }

}