• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • 2026 staff recruitment is open! Check it out and consider applying!

OTClientV8 disable functions

Tbol

Well-Known Member
Joined
Apr 7, 2019
Messages
625
Reaction score
71
Hello got question so i edited tool.lua hp.lua with some custom stuff and deleted some functions, but i noticed inside %appdata% you can just import/inject new tool.lua and hp.lua and so you will basically bypass it and you be able to inject custom shit yourself. How can i prevent it if someone tries to change those files it wont work basically would give error or something
Post automatically merged:

Or im tripping once you edit it, you cannot override it by injecting it in %appdata%, because testing now and it looks like you cannot edit it just with appdata you need to decrypt entire client and edit game_bot aswell
 
Last edited:
OTCv8 bot files are not encrypted and cannot be, because config of player (item IDs, waypoints, monsters to attack etc.) is saved in these files.
There are special lines in C++ to do not encrypt/decrypt game_bot ex.:

You can just allow bot (default) or remove it:

If you edited encrypt and decrypt keys in OTCv8 src/framework/util/crypt.cpp:
and recompiled it. It will be harder to edit other OTCv8 files. Not impossible, but much harder for random OTS player.

Anyway, there is no way to block bot on client side. To really block bot, you have to implement 'cam system' ( GitHub - gesior/tmp-cams-system (https://github.com/gesior/tmp-cams-system) ) and some tool to analyse cam files.
 
My main goal is not to remove the bot completely, but i deleted macro scripts from game_bot because dont want to allow custom scripts only ones already in bot, since i did that now im trying somehow to protect it so they wont just go to appdata and replace for example tools.lua and macro editor will appear again without any effort
 
There is a file that tells the encrypter what to ignore. You can modify it to allow the game_bot folder to encrypt. You will also need to tell it to only allow certain folders to be loaded.
 
There is a file that tells the encrypter what to ignore. You can modify it to allow the game_bot folder to encrypt. You will also need to tell it to only allow certain folders to be loaded.
But didnt gesior said "BOT CANNOT BE ENCRYPTED" but yea all i would want to encrypt is {tools.lua, hp.lua, looting.lua, editor.lua} inside default_configs/cavebot for a harder injection of macro scripts so mainly tools.lua because thats where it is
 
I misinterpreted when I talked about encrypting it. What you can do is make it so anytime the client opens it removes any changed files from the bot folder. So what I did was make it so the client checked the folder and if it was different from what I expected it would remove any extra files including if they try to add code to an existing file. So I wasn't able to encrypt it but I was able to stop people from being able to modify the files and run the client.
 
I misinterpreted when I talked about encrypting it. What you can do is make it so anytime the client opens it removes any changed files from the bot folder. So what I did was make it so the client checked the folder and if it was different from what I expected it would remove any extra files including if they try to add code to an existing file. So I wasn't able to encrypt it but I was able to stop people from being able to modify the files and run the client.
Wtf how you did that. Share tutorial please 😄
 
I cant really get into the tutorial as it was trial and error but here is what I modified in data/modules/game_bot/bot.lua

The folder I allowed with the files inside was called SW_BOT. Whenever the client opened it would rewrite the SW_BOT files and ignore any other bot files. I also disabled downloading other bots, ect.

Keep in mind this change was implemented with other checks to make sure the client was mine and things like that. This change alone is not sufficient but its a good place to start to weed out the normal person from modifying the bot.

LUA:
function edit()
  local configs = g_resources.listDirectoryFiles("/bot", false, false)
  editWindow.manager.upload.config:clearOptions()
  for i=1,#configs do
    if configs[i] == "SW_BOT" then
        editWindow.manager.upload.config:addOption(configs[i])
    end
  end
  editWindow.manager.download.config:setText("")
 
  editWindow:show()
  editWindow:focus()
  editWindow:raise()
end

function createDefaultConfigs()
  local defaultConfigFiles = g_resources.listDirectoryFiles("default_configs", false, false)
  for i, config_name in ipairs(defaultConfigFiles) do
    if config_name == "SW_BOT" then
  
      g_resources.makeDir("/bot/" .. config_name)
      if not g_resources.directoryExists("/bot/" .. config_name) then
        return onError("Can't create /bot/" .. config_name .. " directory in " .. g_resources.getWriteDir())
      end

      local defaultConfigFiles = g_resources.listDirectoryFiles("default_configs/" .. config_name, true, false)
      for i, file in ipairs(defaultConfigFiles) do
        local baseName = file:split("/")
        baseName = baseName[#baseName]
        if g_resources.directoryExists(file) then
          g_resources.makeDir("/bot/" .. config_name .. "/" .. baseName)
        
          if not g_resources.directoryExists("/bot/" .. config_name .. "/" .. baseName) then
            return onError("Can't create /bot/" .. config_name  .. "/" .. baseName .. " directory in " .. g_resources.getWriteDir())
          end
        
          local defaultConfigFiles2 = g_resources.listDirectoryFiles("default_configs/" .. config_name .. "/" .. baseName, true, false)
          for i, file in ipairs(defaultConfigFiles2) do
            local baseName2 = file:split("/")
            baseName2 = baseName2[#baseName2]
            local contents = g_resources.fileExists(file) and g_resources.readFileContents(file) or ""
            if contents:len() > 0 then
              g_resources.writeFileContents("/bot/" .. config_name .. "/" .. baseName .. "/" .. baseName2, contents)
            end
          end
        else
          local contents = g_resources.fileExists(file) and g_resources.readFileContents(file) or ""
        
          if contents:len() > 0 then
            g_resources.writeFileContents("/bot/" .. config_name .. "/" .. baseName, contents)
          end
        end
      end
    end
  end
end

function uploadConfig()
  -- local config = editWindow.manager.upload.config:getCurrentOption().text
  -- local archive = compressConfig(config)
  -- if not archive then
      -- return displayErrorBox(tr("Config upload failed"), tr("Config %s is invalid (can't be compressed)", config))
  -- end
  -- if archive:len() > 1024 * 1024 then
      -- return displayErrorBox(tr("Config upload failed"), tr("Config %s is too big, maximum size is 1024KB. Now it has %s KB.", config, math.floor(archive:len() / 1024)))
  -- end
 
  -- local infoBox = displayInfoBox(tr("Uploading config"), tr("Uploading config %s. Please wait.", config))
 
  -- HTTP.postJSON(configManagerUrl .. "?config=" .. config:gsub("%s+", "_"), archive, function(data, err)
    -- if infoBox then
      -- infoBox:destroy()
    -- end
    -- if err or data["error"] then    
      -- return displayErrorBox(tr("Config upload failed"), tr("Error while upload config %s:\n%s", config, err or data["error"]))
    -- end
    -- displayInfoBox(tr("Succesful config upload"), tr("Config %s has been uploaded.\n%s", config, data["message"]))
  -- end)
end

function downloadConfig()
  -- local hash = editWindow.manager.download.config:getText()
  -- if hash:len() == 0 then
      -- return displayErrorBox(tr("Config download error"), tr("Enter correct config hash"))
  -- end
  -- local infoBox = displayInfoBox(tr("Downloading config"), tr("Downloading config with hash %s. Please wait.", hash))
  -- HTTP.download(configManagerUrl .. "?hash=" .. hash, hash .. ".zip", function(path, checksum, err)
    -- if infoBox then
      -- infoBox:destroy()
    -- end
    -- if err then
      -- return displayErrorBox(tr("Config download error"), tr("Config with hash %s cannot be downloaded", hash))    
    -- end
    -- modules.client_textedit.show("", {
      -- title="Enter name for downloaded config",
      -- description="Config with hash " .. hash .. " has been downloaded. Enter name for new config.\nWarning: if config with same name already exist, it will be overwritten!",
      -- width=500
    -- }, function(configName)
      -- decompressConfig(configName, "/downloads/" .. path)
      -- refresh()
      -- edit()
    -- end)
  -- end)
end
 
Back
Top