Jump to content

[LUA/C++] Captcha Anti Bot


Recommended Posts

Hello community,

I created some time this method to reduce the use of bots on my server, this code was written for anti metins farm but can be adapted for monsters too.
The code was made in a few hours and could be improved a lot more, but as it stands it works perfectly.

Logic

  • When the player destroys 30 metins, the captcha will appear and the player will be stunned at the same time.
  • The player has only 3 attempts, if he fails all 3 times he is teleported to the city.
  • The stun is only removed when the captcha is successfully completed.

As I said, this is not a WOW solution, but it can help as it has helped me on my server.
For those who really want to spend time creating a more effective solution, I recommend creating a captcha in c++ with encrypted connection client -> server.

Don’t forget to update the values in the quest according to your item_proto.

Lua

This is the hidden content, please

C++
This is the hidden content, please

quest_functions
This is the hidden content, please

Edited by Papix
  • Metin2 Dev 112
  • Eyes 3
  • Think 1
  • Good 33
  • muscle 1
  • Love 7
  • Love 55
Link to comment
Share on other sites

1 hour ago, BadiuAndrei said:

attempt to call field `is_metin' (a nil value), i have this in sys i added the pc.is_metin in quest_functions

You need to add this function in the source, not just declare something in quest_functions that is not in the source

  • Good 1
Link to comment
Share on other sites

  • Premium

Didn't test, don't care, wrote in notepad in 5 min spare. This 'system' shouldn't be done in Lua btw.

But if you really want make such an abomination, please, do things properly at the very least:

define STUN_AFFECT_ID 210

define FALSE_ITEMS_NUM 3 -- How many false items should be in the selection.
define FAILED_COUNT_LIMIT 3 -- Warp to village when failing the captcha this amount of times.
define METIN_KILL_LIMIT 50 -- Show captcha upon destroying this amount of metinstones.

quest anti_bot_captcha begin
    state start begin
        function setting()
            return {
                ["true_vnums"] = {101129, 9600, 12829, 2169, 11839, 12789, 71107, 79, 2099, 199, 2159, 3169, 2139, 5349, 1139, 101006, 12809, 7009, 13109, 7029, 189, 39, 7019, 29, 101005},
                ["fake_vnums"] = {
                    11299, 17229, 7379, 2079, 101119, 20509, 2129, 18089, 11819, 129, 13089,
                    89, 69, 11849, 101141, 469, 12849, 101004, 16579, 2069, 101140, 14579, 169,
                    2039, 15459, 11899, 2019, 101144, 11499, 20259, 3199, 139, 101109, 7059, 2109,
                    13169, 17709, 14229, 2059, 7039, 99, 49, 101143, 13069, 18099, 11699, 479, 15449,
                    179, 2049, 5129, 20009, 59, 2089, 2379, 9830, 11829, 20759, 101142, 119, 2179, 2009,
                    2119, 16229, 11809, 101139, 19, 2029, 1349, 11859, 2179, 13149, 7049, 13129, 2149
                }
            };
        end -- function

        function block_player()
            pc.setqf("status", 1); -- Unused, but can be useful.
            pc.affect_stun();
        end -- function

        function unblock_player()
            pc.setqf("status", 0); -- Unused, but can be useful.
            pc.setqf("kill_count", 0);
            pc.setqf("failed_count", 0);
            affect.remove(STUN_AFFECT_ID);
        end -- function

        function captcha_response(is_correct)
            if (is_correct) then
                anti_bot_captcha.unblock_player();
                return;
            end -- if

            pc.setqf("failed_count", pc.getqf("failed_count") + 1);
            if (pc.getqf("failed_count") >= FAILED_COUNT_LIMIT) then
                pc.setqf("failed_count", 0);
                notice("[Captcha] Fail limit reached. Warping you back to your village..")
                warp_to_village();
                return;
            end -- if

            say_reward(string.format("Wrong captcha! (Attempts remaining: %d)", FAILED_COUNT_LIMIT - pc.getqf("failed_count")))
            anti_bot_captcha.show_captcha();
        end -- function

        function show_captcha()
            local setting = anti_bot_captcha.setting();
            local true_item = table_get_random_item(setting["true_vnums"]);

            say("What is the name of this item?")
            say_item_vnum(true_item);
            say("[ENTER][ENTER]")

            local random_item, chosen_items = 0, {};
            table.insert(chosen_items, item_name(true_item));
  
            for _ = 1, FALSE_ITEMS_NUM do
                -- table_get_random_item_except (https://metin2.dev/topic/15905-syreldars-quest-functions/)
                random_item = table_get_random_item_except(setting["fake_vnums"], chosen_items);
                table.insert(chosen_items, item_name(random_item));
            end -- for

            -- table_shuffle (https://metin2.dev/topic/15905-syreldars-quest-functions/)
            local options = table_shuffle(chosen_items);
            local selection = select(unpack(options));
            anti_bot_captcha.captcha_response(options[selection] == item_name(true_item))
        end -- function

        when kill with not npc.is_pc() and npc.is_metin() begin
            pc.setqf("kill_count", pc.getqf("kill_count")+1);

            if (pc.getqf("kill_count") >= METIN_KILL_LIMIT) then
                anti_bot_captcha.block_player();
                anti_bot_captcha.show_captcha();
            end -- if
        end -- when
    end -- state
end -- quest

 

Thanks for the contribution, I guess.

Edited by Syreldar
  • Love 1

 

"Nothing's free in this life.

Ignorant people have an obligation to make up for their ignorance by paying those who help them.

Either you got the brains or cash, if you lack both you're useless."

Syreldar

Link to comment
Share on other sites

42 minutes ago, Syreldar said:

Didn't test, don't care, wrote in notepad in 5 min spare. This 'system' shouldn't be done in Lua btw.

But if you really want make such an abomination, please, do things properly at the very least:

define STUN_AFFECT_ID 210

define FALSE_ITEMS_NUM 3 -- How many false items should be in the selection.
define FAILED_COUNT_LIMIT 3 -- Warp to village when failing the captcha this amount of times.
define METIN_KILL_LIMIT 50 -- Show captcha upon destroying this amount of metinstones.

quest anti_bot_captcha begin
    state start begin
        function setting()
            return {
                ["true_vnums"] = {101129, 9600, 12829, 2169, 11839, 12789, 71107, 79, 2099, 199, 2159, 3169, 2139, 5349, 1139, 101006, 12809, 7009, 13109, 7029, 189, 39, 7019, 29, 101005},
                ["fake_vnums"] = {
                    11299, 17229, 7379, 2079, 101119, 20509, 2129, 18089, 11819, 129, 13089,
                    89, 69, 11849, 101141, 469, 12849, 101004, 16579, 2069, 101140, 14579, 169,
                    2039, 15459, 11899, 2019, 101144, 11499, 20259, 3199, 139, 101109, 7059, 2109,
                    13169, 17709, 14229, 2059, 7039, 99, 49, 101143, 13069, 18099, 11699, 479, 15449,
                    179, 2049, 5129, 20009, 59, 2089, 2379, 9830, 11829, 20759, 101142, 119, 2179, 2009,
                    2119, 16229, 11809, 101139, 19, 2029, 1349, 11859, 2179, 13149, 7049, 13129, 2149
                }
            };
        end -- function

        function block_player()
            pc.setqf("status", 1); -- Unused, but can be useful.
            pc.affect_stun();
        end -- function

        function unblock_player()
            pc.setqf("status", 0); -- Unused, but can be useful.
            pc.setqf("kill_count", 0);
            pc.setqf("failed_count", 0);
            affect.remove(STUN_AFFECT_ID);
        end -- function

        function captcha_response(is_correct)
            if (is_correct) then
                anti_bot_captcha.unblock_player();
                return;
            end -- if

            pc.setqf("failed_count", pc.getqf("failed_count") + 1);
            if (pc.getqf("failed_count") >= FAILED_COUNT_LIMIT) then
                pc.setqf("failed_count", 0);
                notice("[Captcha] Fail limit reached. Warping you back to your village..")
                warp_to_village();
                return;
            end -- if

            say_reward(string.format("Wrong captcha! (Attempts remaining: %d)", FAILED_COUNT_LIMIT - pc.getqf("failed_count")))
            anti_bot_captcha.show_captcha();
        end -- function

        function show_captcha()
            local setting = anti_bot_captcha.setting();
            local true_item = table_get_random_item(setting["true_vnums"]);

            say("What is the name of this item?")
            say_item_vnum(true_item);
            say("[ENTER][ENTER]")

            local random_item, chosen_items, except_items = 0, {}, {};
            for _ = 1, FALSE_ITEMS_NUM do
                -- table_get_random_item_except (https://metin2.dev/topic/15905-syreldars-quest-functions/)
                random_item = table_get_random_item_except(setting["fake_vnums"], except_items);
                table.insert(chosen_items, item_name(random_item));
                table.insert(except_items, random_item);
            end -- for

            table.insert(chosen_items, item_name(true_item));

            -- table_shuffle (https://metin2.dev/topic/15905-syreldars-quest-functions/)
            local options = table_shuffle(chosen_items);
            local selection = select(unpack(options));
            anti_bot_captcha.captcha_response(options[selection] == item_name(true_item))
        end -- function

        when kill with not npc.is_pc() and npc.is_metin() begin
            pc.setqf("kill_count", pc.getqf("kill_count")+1);

            if (pc.getqf("kill_count") >= METIN_KILL_LIMIT) then
                anti_bot_captcha.block_player();
                anti_bot_captcha.show_captcha();
            end -- if
        end -- when
    end -- state
end -- quest

 

Thanks for the contribution, I guess.

As I said I made the code in a short time and it helped me in my project, I already mentioned in the topic that it could be improved but as I published it works without problems.

Thanks for your contribution, I think :kekw:

  • Love 1
Link to comment
Share on other sites

Announcements



×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.