Description: This anti-cavebot system differs from the standard (do-the-math) technique. Every now and then after a few requirements are met players may face themselves with a chest bonus. This is clearly indicated by animated text (deprecated in newer versions, you will have to remove) and a treasure chest. Players will autowalk (not supported in older versions, you may have to remove) to the chest until they click it. If they are quick enough to get away from the autowalk they will be teleported back on to the chest. Once the player clicks the chest they will receive a bonus which consists of whatever loot of the monster they were targeting (slightly boosted loot rate for better rewards). However, if they do not click it they will keep being drawn to it which is the first method of stopping the cavebotting. The second portion to this is after a certain time has passed they will be skulled by the system and a global broadcast will be issued for anyone wanting to claim their lives. The system will also drain their stamina 20 minutes every time this happens. Nowadays with bots so modern it is hard to make a way to stop cavebotting but I did my best to thwart this. While this script is more effective through obscurity and loses a bit of effectiveness now that it is out to the public and botters can see the insides it is still a viable solution. It works by using two items, the chest and an invisible item overlay. The player never actually clicks the chest but actually the invisible item put on top of it. You may be wondering why, well this is not all the invisible item is used for. The item is spawned without the chest frequently under the player. In theory if the player is using a script to look for the invisible itemid and click it they will click it even if it spawns under them without them knowing. They are added to the channel log for suspicion of botting (PLEASE NOTE: just because someone ends up in the log once or twice does not mean they are botting, they could have been clicking under them while it spawned. The log is for knowing what's going on, if someone clicks 20 of them in a row and does it consistently they are most likely using a script.) I've used this script on my realmap server and the highscores stayed believable. Players told me it didn't really get in the way and they only ones who didn't like it were the ones it was catching That's all thank you and please donate if you like it.
Directions: create a file named "anti_cavebot.xml" and paste the contents in the code box below into the file.
Commands:
Directions: create a file named "anti_cavebot.xml" and paste the contents in the code box below into the file.
Commands:
/bonuses - shows a list of ever player with an active bonus chest
NOTE: the commands below still have to meet the checking criteria or they won't work.
/cavebot all - initiates the cavebot check manually (usually done automatically through a globalevent).
/cavebot playername - same as above but only for a specific player
NOTE: the commands below still have to meet the checking criteria or they won't work.
/cavebot all - initiates the cavebot check manually (usually done automatically through a globalevent).
/cavebot playername - same as above but only for a specific player
Code:
[size=2][color=#f030d0]<?xml[/color] [color=#0070e6]version[/color]=[color=#ff6633]"1.0"[/color] [color=#0070e6]encoding[/color]=[color=#ff6633]"UTF-8"[/color][color=#f030d0]?>[/color]
[color=#f030d0]<mod[/color] [color=#0070e6]name[/color]=[color=#ff6633]"Anti CaveBot System"[/color] [color=#0070e6]version[/color]=[color=#ff6633]"3.1"[/color] [color=#0070e6]author[/color]=[color=#ff6633]"Cavitt Glover"[/color] [color=#0070e6]contact[/color]=[color=#ff6633]"http://otland.net/members/syntax/"[/color] [color=#0070e6]enabled[/color]=[color=#ff6633]"yes"[/color][color=#f030d0]>[/color]
[color=#f030d0]<config[/color] [color=#0070e6]name[/color]=[color=#ff6633]"AntiBot_lib"[/color][color=#f030d0]>[/color]<![CDATA[
blocked_targets = {
[color=#ff6633]"Training Monk"[/color],
[color=#ff6633]"Walter"[/color],
[color=#ff6633]"Pythius The Rotten"[/color],
[color=#ff6633]"Azerus"[/color],
[color=#ff6633]"Annihilon"[/color],
[color=#ff6633]"Apprentice Sheng"[/color],
[color=#ff6633]"Ashmunrah"[/color],
[color=#ff6633]"Brutus Bloodbeard"[/color],
[color=#ff6633]"Chizzoron the Distorter"[/color],
[color=#ff6633]"Countess Sorrow"[/color],
[color=#ff6633]"Deadeye Devious"[/color],
[color=#ff6633]"Demodras"[/color],
[color=#ff6633]"Dipthrah"[/color],
[color=#ff6633]"Dire Penguin"[/color],
[color=#ff6633]"Dracola"[/color],
[color=#ff6633]"Earth Overlord"[/color],
[color=#ff6633]"Energy Overlord"[/color],
[color=#ff6633]"Ferumbras"[/color],
[color=#ff6633]"Fire Overlord"[/color],
[color=#ff6633]"Ghazbaran"[/color],
[color=#ff6633]"Golgordan"[/color],
[color=#ff6633]"Grorlam"[/color],
[color=#ff6633]"Hellgorak"[/color],
[color=#ff6633]"Ice Overlord"[/color],
[color=#ff6633]"Latrivan"[/color],
[color=#ff6633]"Lethal Lissy"[/color],
[color=#ff6633]"Lord of the Elements"[/color],
[color=#ff6633]"Madareth"[/color],
[color=#ff6633]"Mahrdis"[/color],
[color=#ff6633]"Man In The Cave"[/color],
[color=#ff6633]"Massacre"[/color],
[color=#ff6633]"Morgaroth"[/color],
[color=#ff6633]"Morguthis"[/color],
[color=#ff6633]"Mr. Punish"[/color],
[color=#ff6633]"Necropharus"[/color],
[color=#ff6633]"Omruc"[/color],
[color=#ff6633]"Orshabaal"[/color],
[color=#ff6633]"Rahemos"[/color],
[color=#ff6633]"Ron the Ripper"[/color],
[color=#ff6633]"Thalas"[/color],
[color=#ff6633]"The Count"[/color],
[color=#ff6633]"The Handmaiden"[/color],
[color=#ff6633]"The Horned Fox"[/color],
[color=#ff6633]"The Imperor"[/color],
[color=#ff6633]"The Old Widow"[/color],
[color=#ff6633]"The Plasmother"[/color],
[color=#ff6633]"Tiquandas Revenge"[/color],
[color=#ff6633]"Ushuriel"[/color],
[color=#ff6633]"Vashresamun"[/color],
[color=#ff6633]"Warlord Ruzad"[/color],
[color=#ff6633]"Zugurosh"[/color],
[color=#ff6633]"Zulazza The Corruptor"[/color],
[color=#ff6633]"Achad"[/color],
[color=#ff6633]"Avalanche"[/color],
[color=#ff6633]"Axeitus Headbanger"[/color],
[color=#ff6633]"Baron Brute"[/color],
[color=#ff6633]"Bloodpaw"[/color],
[color=#ff6633]"Bovinus"[/color],
[color=#ff6633]"Coldheart"[/color],
[color=#ff6633]"Colerian The Barbarian"[/color],
[color=#ff6633]"Cursed Gladiator"[/color],
[color=#ff6633]"Darakan The Executioner"[/color],
[color=#ff6633]"Deathbringer"[/color],
[color=#ff6633]"Doomhowl"[/color],
[color=#ff6633]"Drasilla"[/color],
[color=#ff6633]"Dreadwing"[/color],
[color=#ff6633]"Fallen Mooh'tah Master Ghar"[/color],
[color=#ff6633]"Fatality"[/color],
[color=#ff6633]"Frostfur"[/color],
[color=#ff6633]"Glitterscale"[/color],
[color=#ff6633]"Gnorre Chyllson"[/color],
[color=#ff6633]"Grimgor Guteater"[/color],
[color=#ff6633]"Haunter"[/color],
[color=#ff6633]"Heoni"[/color],
[color=#ff6633]"Incineron"[/color],
[color=#ff6633]"Koshei The Deathless"[/color],
[color=#ff6633]"Kreebosh The Exile"[/color],
[color=#ff6633]"Mad Technomancer"[/color],
[color=#ff6633]"Menace"[/color],
[color=#ff6633]"Mutated Zalamon"[/color],
[color=#ff6633]"Norgle Glacierbeard"[/color],
[color=#ff6633]"Orcus The Cruel"[/color],
[color=#ff6633]"Rocko"[/color],
[color=#ff6633]"Rocky"[/color],
[color=#ff6633]"Snake God Essence"[/color],
[color=#ff6633]"Snake Thing"[/color],
[color=#ff6633]"Slim"[/color],
[color=#ff6633]"Spirit Of Earth"[/color],
[color=#ff6633]"Spirit Of Fire"[/color],
[color=#ff6633]"Spirit Of Water"[/color],
[color=#ff6633]"Svoren The Mad"[/color],
[color=#ff6633]"The Axeorcist"[/color],
[color=#ff6633]"The Dark Dancer"[/color],
[color=#ff6633]"The Dreadorian"[/color],
[color=#ff6633]"The Hag"[/color],
[color=#ff6633]"The Hairy One"[/color],
[color=#ff6633]"The Keeper"[/color],
[color=#ff6633]"The Masked Marauder"[/color],
[color=#ff6633]"The Obliverator"[/color],
[color=#ff6633]"The Pit Lord"[/color],
[color=#ff6633]"Tirecz"[/color],
[color=#ff6633]"Tremorak"[/color],
[color=#ff6633]"Webster"[/color]
}
function checkCaveBotter(player)
for _,cid in ipairs(getPlayersOnline()) do
if getCreatureName(cid) == player or player == [color=#ff6633]"all"[/color] then
local target = getCreatureTarget(cid)
local hpratio = (getCreatureHealth(cid)/getCreatureMaxHealth(cid)) * [color=#8016ff]100[/color]
local not_checked = getCreatureStorage(cid, [color=#ff6633]"Bot_Check"[/color]) < [color=#8016ff]0[/color]
if(isMonster(target) and hpratio [color=#f030d0]>[/color] [color=#8016ff]20[/color] and not_checked)then
local valid = true
local targetName = getCreatureName(target)
for i = [color=#8016ff]1[/color], #blocked_targets do
if targetName == blocked_targets[i] then
valid = false
end
end
if(valid)then
local createPos = getClosestFreeTile(cid, getThingPosition(cid), true, false)
if doSetItemActionId(doCreateItem([color=#8016ff]10049[/color], [color=#8016ff]1[/color], createPos), [color=#8016ff]90000[/color] + getPlayerGUID(cid)) then
doCreatureSetStorage(cid, [color=#ff6633]"Bot_Check"[/color], [color=#8016ff]1[/color])
doCreatureSetStorage(cid, [color=#ff6633]"Bot_Target"[/color], targetName)
addEvent(doSendBotterWarning, [color=#8016ff]5[/color] * [color=#8016ff]60[/color] * [color=#8016ff]1000[/color], cid, [color=#8016ff]5[/color])
loopCheck(cid, [color=#ff6633]"BONUS!"[/color], createPos)
end
end
end
end
end
end
function loopCheck(cid, text, pos)
local checked = getCreatureStorage(cid, [color=#ff6633]"Bot_Check"[/color]) [color=#f030d0]>[/color] [color=#8016ff]0[/color]
if(isPlayer(cid) and checked)then
--remove field
local field = getTileItemByType(pos, ITEM_TYPE_MAGICFIELD)
if(field.itemid [color=#f030d0]>[/color] [color=#8016ff]0[/color]) then
doRemoveItem(field.uid)
end
--remove any on the tile
local invisItem = getTileItemById(pos, [color=#8016ff]10049[/color])
if (invisItem.uid [color=#f030d0]>[/color] [color=#8016ff]0[/color]) then
doRemoveItem(invisItem.uid)
doSetItemActionId(doCreateItem([color=#8016ff]10049[/color], [color=#8016ff]1[/color], pos), [color=#8016ff]90000[/color] + getPlayerGUID(cid))
else
doSetItemActionId(doCreateItem([color=#8016ff]10049[/color], [color=#8016ff]1[/color], pos), [color=#8016ff]90000[/color] + getPlayerGUID(cid))
end
doSendMagicEffect(pos, CONST_ME_FIREWORK_YELLOW)
doSendAnimatedText(pos, text, COLOR_DARKYELLOW)
doSteerCreature(cid, pos)
if getDistanceBetween(getThingPosition(cid), pos) [color=#f030d0]>[/color] [color=#8016ff]9[/color] then
doTeleportThing(cid, pos)
end
addEvent(loopCheck, [color=#8016ff]500[/color], cid, text, pos)
end
end
function doSendBotterWarning(cid, timeToKill)
if not isPlayer(cid) then
return true
end
if getCreatureStorage(cid, [color=#ff6633]"Bot_Check"[/color]) ~= [color=#8016ff]1[/color] then
return true
end
if timeToKill [color=#f030d0]>[/color] [color=#8016ff]0[/color] then
doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, [color=#ff6633]"You are suspected of cave-botting.[/color][color=#4a9400]\n[/color][color=#ff6633]Punishment will occur in "[/color]..timeToKill..[color=#ff6633]" minutes.[/color][color=#4a9400]\n[/color][color=#ff6633]Use the bonus near you to avoid punishment."[/color])
addEvent(doSendBotterWarning, [color=#8016ff]60[/color] * [color=#8016ff]1000[/color], cid, timeToKill-[color=#8016ff]1[/color])
elseif getCreatureSkullType(cid) == SKULL_NONE then
doCreatureSetSkullType(cid, SKULL_WHITE)
doBroadcastMessage(getCreatureName(cid)..[color=#ff6633]" has been skulled for cave-botting!"[/color], MESSAGE_STATUS_WARNING)
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, [color=#ff6633]"The server has removed 20 minutes of your stamina for botting."[/color])
doPlayerSetStamina(cid, getPlayerStamina(cid) - [color=#8016ff]20[/color])
addEvent(doSendBotterWarning, [color=#8016ff]60[/color] * [color=#8016ff]1000[/color], cid, timeToKill)
else
addEvent(doSendBotterWarning, [color=#8016ff]60[/color] * [color=#8016ff]1000[/color], cid, timeToKill)
end
end
]][color=#f030d0]></config>[/color]
[color=#f030d0]<talkaction[/color] [color=#0070e6]words[/color]=[color=#ff6633]"/botters"[/color] [color=#0070e6]access[/color]=[color=#ff6633]"2"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"buffer"[/color][color=#f030d0]>[/color]<![CDATA[
local str = [color=#ff6633]"Players with bonuses:[/color][color=#4a9400]\n\n[/color][color=#ff6633]"[/color]
for _,pid in ipairs(getPlayersOnline()) do
if getCreatureStorage(pid, [color=#ff6633]"Bot_Check"[/color]) == [color=#8016ff]1[/color] then
str = str..getPlayerName(pid)..[color=#ff6633]"[/color][color=#4a9400]\n[/color][color=#ff6633]"[/color]
end
end
doPlayerPopupFYI(cid, str)
]][color=#f030d0]></talkaction>[/color]
[color=#f030d0]<talkaction[/color] [color=#0070e6]words[/color]=[color=#ff6633]"/cavebot"[/color] [color=#0070e6]access[/color]=[color=#ff6633]"2"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"buffer"[/color][color=#f030d0]>[/color]<![CDATA[
domodlib('AntiBot_lib')
if isPlayer(getCreatureByName(param)) or param == [color=#ff6633]"all"[/color] then
checkCaveBotter(param)
else
doPlayerSendCancel(cid, [color=#ff6633]"Player does not exist!"[/color])
end
]][color=#f030d0]></talkaction>[/color]
[color=#f030d0]<globalevent[/color] [color=#0070e6]name[/color]=[color=#ff6633]"ACB_Check"[/color] [color=#0070e6]interval[/color]=[color=#ff6633]"1800000"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"buffer"[/color][color=#f030d0]>[/color]<![CDATA[
domodlib('AntiBot_lib')
addEvent(checkCaveBotter, math.random([color=#8016ff]1000[/color],[color=#8016ff]240000[/color]), [color=#ff6633]"all"[/color])
]][color=#f030d0]></globalevent>[/color]
[color=#f030d0]<event[/color] [color=#0070e6]type[/color]=[color=#ff6633]"login"[/color] [color=#0070e6]name[/color]=[color=#ff6633]"ACB_Login"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"buffer"[/color][color=#f030d0]>[/color]<![CDATA[
doCreatureSetStorage(cid, [color=#ff6633]"Bot_Check"[/color], -[color=#8016ff]1[/color])
registerCreatureEvent(cid, [color=#ff6633]"ACB_Direction"[/color])
]][color=#f030d0]></event>[/color]
[color=#f030d0]<event[/color] [color=#0070e6]type[/color]=[color=#ff6633]"target"[/color] [color=#0070e6]name[/color]=[color=#ff6633]"ACB_Direction"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"script"[/color][color=#f030d0]>[/color]<![CDATA[
function removeSparkle(pos)
local id = getTileItemById(pos, [color=#8016ff]10049[/color])
if(id.itemid [color=#f030d0]>[/color] [color=#8016ff]0[/color])then
doRemoveItem(id.uid)
end
end
function onTarget(cid, target)
if isMonster(target) and getCreatureName(target) ~= [color=#ff6633]"Training Monk"[/color] and getCreatureStorage(cid, [color=#ff6633]"Bot_Check"[/color]) == -[color=#8016ff]1[/color] then
local item = doCreateItem([color=#8016ff]10049[/color], [color=#8016ff]1[/color], getThingPosition(cid))
if(item)then
doSetItemActionId(item, [color=#8016ff]90000[/color])
end
addEvent(removeSparkle, [color=#8016ff]1000[/color], getThingPosition(cid))
end
return true
end
]][color=#f030d0]></event>[/color]
[color=#f030d0]<channel[/color] [color=#0070e6]id[/color]=[color=#ff6633]"14"[/color] [color=#0070e6]name[/color]=[color=#ff6633]"Anti-Bot Log"[/color] [color=#0070e6]access[/color]=[color=#ff6633]"2"[/color] [color=#0070e6]override[/color]=[color=#ff6633]"yes"[/color][color=#f030d0]/>[/color]
[color=#f030d0]<movevent[/color] [color=#0070e6]type[/color]=[color=#ff6633]"StepOut"[/color] [color=#0070e6]itemid[/color]=[color=#ff6633]"10049"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"script"[/color][color=#f030d0]>[/color]<![CDATA[
function onStepOut(cid, item, position, fromPosition)
if isPlayer(cid) and item.actionid == [color=#8016ff]90000[/color] then
doRemoveItem(item.uid)
end
return true
end
]][color=#f030d0]></movevent>[/color]
[color=#f030d0]<movevent[/color] [color=#0070e6]type[/color]=[color=#ff6633]"RemoveItem"[/color] [color=#0070e6]itemid[/color]=[color=#ff6633]"10049"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"script"[/color][color=#f030d0]>[/color]<![CDATA[
function onRemoveItem(moveItem, tileItem, position, cid)
if moveItem.uid [color=#f030d0]>[/color] [color=#8016ff]0[/color] then
doRemoveItem(moveItem.uid)
doSetItemActionId(doCreateItem([color=#8016ff]10049[/color], [color=#8016ff]1[/color], position), moveItem.actionid)
end
return true
end
]][color=#f030d0]></movevent>[/color]
[color=#f030d0]<action[/color] [color=#0070e6]itemid[/color]=[color=#ff6633]"10049"[/color] [color=#0070e6]event[/color]=[color=#ff6633]"script"[/color][color=#f030d0]>[/color]<![CDATA[
function onUse(cid, item, fromPosition, itemEx, toPosition)
if (item.actionid == [color=#8016ff]90000[/color]) then
for _,user in ipairs(getChannelUsers([color=#8016ff]14[/color])) do
doPlayerSendChannelMessage(user, [color=#ff6633]""[/color], getCreatureName(cid)..[color=#ff6633]" suspected of bypassing bonus chests!"[/color], TALKTYPE_CHANNEL_W, [color=#8016ff]14[/color])
end
doRemoveItem(item.uid)
end
if item.actionid <= [color=#8016ff]90000[/color] or item.actionid [color=#f030d0]>[/color]= [color=#8016ff]100000[/color] then
return true
end
domodlib('AntiBot_lib')
if getPlayerGUID(cid) == (item.actionid - [color=#8016ff]90000[/color]) then
local loot = getMonsterLootList(getCreatureStorage(cid, [color=#ff6633]"Bot_Target"[/color]))
local index = [color=#8016ff]1[/color]
local chance = math.random([color=#8016ff]1[/color], [color=#8016ff]100000[/color])
repeat
index = math.random([color=#8016ff]1[/color], #loot)
until (loot[index].chance * [color=#8016ff]10[/color]) [color=#f030d0]>[/color]= chance and not isItemContainer(loot[index].id)
local count = math.random([color=#8016ff]1[/color], loot[index].count)
doPlayerAddItem(cid, loot[index].id, count)
local itemName = getItemNameById(loot[index].id)
if count [color=#f030d0]>[/color] [color=#8016ff]1[/color] then
itemName = getItemPluralNameById(loot[index].id)
end
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, string.format([color=#ff6633]"You received %d %s as a hunting bonus!"[/color], count, itemName))
doCreatureSetStorage(cid, [color=#ff6633]"Bot_Check"[/color], -[color=#8016ff]1[/color])
doCreatureSetStorage(cid, [color=#ff6633]"Bot_Target"[/color], -[color=#8016ff]1[/color])
doRemoveItem(item.uid)
else
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, [color=#ff6633]"This is not your bonus!"[/color])
end
return true
end
]][color=#f030d0]></action>[/color]
[color=#f030d0]</mod>[/color]
[/size]
Last edited: