Autor: Karpio
Licencja: Rób ta co chcecie, tylko podajcie prawdziwego autora!!!
Testowane na: The Forgotten Server 0.4_DEV.r4086

Wchodzimy do data/talkactions/scripts i tworzymy plik antibot.lua:

antibot.lua
-- Anti Bot System by Karpio
 
local TIME_TO_ANSWER = 14 * 60 * 1000 -- 14 min
local NEXT_CHECK = 30 * 60 -- 30 min
local BLOCK_CHECK = 60 * 60 -- 60 min
local ENABLE_BANISHMENT = true -- set to false if you don't want to banish player
local BANISHMENT_TIME = 3 * 24 * 60 * 60 -- 3 days
local KICK_POSITION = {x = 552, y = 472, z = 7} -- Oxen temple
local KICK_PLAYER = true -- kick player after check
local CHECK_FIELDS = true -- check if player is in pz, nonlogout zone, etc
local LOG_CHECKS = true -- save information about checking in log file
local CHECK_DISTANCE = 10 -- distance between player and target
local USE870 = true -- set to false if we don't use client 8.7+
 
local function getDistanceBetween(fromPosition, toPosition)
	local distance = math.floor(math.sqrt((fromPosition.x-toPosition.x)^2 + (fromPosition.y-toPosition.y)^2))
	return distance
end
 
local function banPlayer(cid)
	if(not isPlayer(cid)) then return end
	if(getPlayerStorageValue(cid, "botCode") < 100) then return end
	if(ENABLE_BANISHMENT) then
		doAddAccountBanishment(getPlayerAccountId(cid), 0, os.time() + BANISHMENT_TIME, 12)
	else
		doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF)
		doTeleportThing(cid, KICK_POSITION)
		doSendMagicEffect(getCreaturePosition(cid), CONST_ME_TELEPORT)
	end
	if(KICK_PLAYER and isPlayer(cid)) then doRemoveCreature(cid) end
	return
end
 
local function send(cid, target)
	if(LOG_CHECKS) then
		local file = io.open(getDataDir().."/logs/bots/AntiBot.log", "a+")
		file:write("["..os.date("%c").."] "..getCreatureName(target).." checked by "..getCreatureName(cid).."\n")
		file:close()
	end
	if(USE870) then
		doPlayerSetCooldown(target, 4, TIME_TO_ANSWER, true)
		doPlayerSetExhaustion(target, 4, TIME_TO_ANSWER, true)
	end
	setPlayerStorageValue(cid, "botNextCheck", os.time() + NEXT_CHECK)
	setPlayerStorageValue(target, "botCode", math.random(math.min(getPlayerLevel(cid),getPlayerLevel(target)) * 1000, math.max(getPlayerLevel(target), getPlayerLevel(cid)) * 1000))
	setPlayerStorageValue(target, "botBlockCheck", os.time() + BLOCK_CHECK)
	addEvent(banPlayer, TIME_TO_ANSWER, target)
	doPlayerSendTextMessage(target, MESSAGE_STATUS_WARNING, "Someone check you as bot. Please write !check "..getPlayerStorageValue(target, "botCode")..", if you don't want to be "..(ENABLE_BANISHMENT and "banned" or "kicked")..".")
	doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, getCreatureName(target).." will be checked by an automated antibot system.")
	return
end
 
 
function onSay(cid, words, param, channel)
	if(param == "") then return doPlayerSendCancel(cid, "Command requires param.") end
	if(tonumber(param)) then
		param = tonumber(param)
		if(getPlayerStorageValue(cid, "botCode") < 100) then return doPlayerSendCancel(cid, "No one will check you.") end
		if(param ~= getPlayerStorageValue(cid, "botCode")) then return doPlayerSendCancel(cid, "Code is not corrected. You have only "..unpack(string.timediff(os.time() - getPlayerStorageValue(cid, "botCode"))).." to write code.") end
		setPlayerStorageValue(cid, "botCode", -1)
		if(USE870) then
			doPlayerSetCooldown(cid, 4, 100, true)
			doPlayerSetExhaustion(cid, 4, 100, true)
		end
		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Code is correct.")
		doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "Have a good game.")
		return true
	else
		local target = getPlayerByNameWildcard(param)
		if(not target) then return doPlayerSendCancel(cid, "Player not found.") end
		if(getPlayerStorageValue(cid, "botNextCheck") > os.time()) then
			return doPlayerSendCancel(cid, "You are exhausted.")
		end
		if(getPlayerStorageValue(target, "botBlockCheck") > os.time()) then
			return doPlayerSendCancel(cid, "This player is protected.")
		end
		if(CHECK_FIELDS) then
			if(getTileInfo(getCreaturePosition(cid)).protection) then return doPlayerSendCancel(cid, "You can not check players from protection zone.") end
			if(getTileInfo(getCreaturePosition(cid)).nologout) then return doPlayerSendCancel(cid, "You can not check players from nologout zone.") end
			if(getTileInfo(getCreaturePosition(target)).protection) then return doPlayerSendCancel(cid, "You can not check players who are in protection zone.") end
			if(getTileInfo(getCreaturePosition(target)).nologout) then return doPlayerSendCancel(cid, "You can not check players who are in nologout zone.") end
		end
		if(CHECK_DISTANCE) then
			if(getDistanceBetween(getCreaturePosition(cid), getCreaturePosition(target)) > CHECK_DISTANCE) then return doPlayerSendCancel(cid, "This player is too far away.") end
		end
		send(cid, target)
		return true
	end
return true
end

Wchodzimy do data/talkactions/talkactions.xml i doklejamy:

talkactions.xml
<talkaction words="!check" event="script" value="antibot.lua"/>

Restartujemy OTS i już chodzi ^^

Użycie: Aby sprawdzić: !check nick Aby odpowiedzieć: !check code

Reszta w konfiguracji na górze skryptu ^^