Skip to content
This repository has been archived by the owner on Dec 9, 2020. It is now read-only.

breuerfelix/king-bot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

king-bot

check out the insights of this project: breuer.dev

Twitch - YouTube - Twitter - Patreon - Discord - Bot Creation Guide

disclaimer: please note that this is a research project. i am by no means responsible for any usage of this tool. use on your own behalf. i'm also not responsible if your accounts get banned due to extensive use of this tool.

this bot does not work anymore! if you still manage to get it running, it will lead to banned accounts.

MIT license built with Selenium built with Python3

table of contents

getting-started

watch the youtube video if you got problems setting up the bot. click here !

  1. install python3 for your system
    1. get python
    2. you need version 3.7 or higher
  2. clone this repository
  3. install packages
    1. open console
    2. goto this repository
    3. run pip install . or pip install -r requirements.txt
  4. download chromedriver for your system (optional)
    1. get chromederiver
    2. move to assets/ folder
  5. edit start.py
    1. insert your credentials (optional)
      1. login without inserting -> see chapter start options
    2. place the actions your bot should do at the end
      1. read documentation for this
      2. read sample_start.py to get an impression
  6. execute script
    1. python start.py
    2. read documentation for options like remote browser or headless browsing
  7. on mac or linux
    1. use python3 and pip3 instead

features

just an overview with method signatures. for details check each chapter.

def start_adventures(interval: int = 100, health: int = 50) -> None:
def start_farming(village: int, farmlists: list, interval: int) -> None:
def start_custom_farmlist(reload: bool = False) -> None:
def celebrate(villages: [], interval: int = 1000) -> None:
def sort_danger_farms(farmlists: list, to_list: int, red: bool, yellow: bool, interval: int = 300) -> None:
def dodge_attack(village: int, interval: int = 600, units: list = [], target: list = [], save_resources: bool = False, units_train: list = []) -> None:
def upgrade_units_smithy(village: int, units: list, interval: int = 1000) -> None:
def start_building(village: int, file_name: str, interval: int = 1800) -> None:
def robber_hideout(village: int, units: dict, interval: int) -> None:
def robber_camp(village: int, units: dict, interval: int) -> None:
def train_troops(village: int, units: list, interval: int) -> None:

farming (travian plus)

the bot will open given village, selects all farmlists from the array, sends them, and go to sleep.
this is by far the simplest implementation of a farm bot.

# sends farmlist with index 1 (the one after the starter list)
# in your first village (index 0) in an interval of 60 seconds
kingbot.start_farming(village=0, farmlists=[1], interval=60)

#sends farmlist 1 and 3 in your second village in an interval of 30 seconds
kingbot.start_farming(1, [1,3], 30)

village:
index of village (0 is the first village)

farmlists:
index of farmlist (0 is the starter list with only 10 farms)
must be an array! you can send multiple lists in this interval

interval:
interval of sending the list in seconds

you can stack as many of them together if you want.
it's also possible to send different farmlist in the same village in different intervals.

sorting out yellow / red farms

note that this feature is not fully tested yet!
i need someone with alot of big farmlists to test this feature for me

this line will let the bot automaticly sort out red or/and yellow farms for you.
it is checking all given farmlists in an interval (in seconds) for danger farms.
if a farm is yellow or red, and you set the equivalent value to True, this farm will be placed onto the farmlist with the index given by the paramter to_list.
the starter farmlist is index 0.

kingbot.sort_danger_farms(farmlists=[0], to_list=1, red=True, yellow=False, interval=240)

farmlists:
array of farmlist indexes (start farmlist is 0)

to_list:
index of the farmlist the 'danger' farms will be put into
-1 if you want the farm to be removed instead of moved to another list

red:
True if you want red farms to be sorted out

yellow:
True if you want also yellow farms to be sorted out

interval:
interval of checking the farmlists in seconds

farmlists as .txt file (no travian plus needed)

this technique is a little bit slower than then one with travian plus.
the bot will manually launch every attack at the rally point.
i only implemented this feature for people who doesn't want to pay for the game and still want to farm only around 200 villages.

you have to create a file named farmlist.txt in assets/ folder, which looks like the following: (attention for separators!)

-26;-34;120;0;1,2
-28;-24;70;0;1,2,3,4
-30;-57;300;0;1,2

pattern:
x-coordinate ; y-coordinate ; time to wait till sending the troops again in seconds ; index of village ; index of unit in the horizontal bar , amount of units

every line represents one farm. the first 2 values are the x- and y-coordinates.
the third value is the time (in seconds) the bot waits until it sends the farm again.
fourth value is the village from where the troops are going to be send off.
the last values (comma separated!) are the amount and index of the unit which is going to be send.
you can find out the index when trying to launch a new attack. you will be asked which village you want to attack and which troops you wanna use.
from left to right, starting at 0, these are the indexes of the units you want to use.
for example (gauls): 0 = phalanx, 1 = swordsman.
if you want to send different units, just stack them at the end.
...0,1,3,4 -> this would send 1 of unit 0 and 4 of unit 3 to this farm.

attention:
adding a unit index of -1 will send all units with max number to this farm.
adding a unit value of -1 will send all units of this type to this farm.

add the following line to your start.py script:

kingbot.start_custom_farmlist(reload=False)

reload:
if you set this value to True the bot will rescan your farmlist file every minute for changing lines
you can add or remove farms without restarting the script

celebrations

the bot will start a small celebration in given villages everytime the queue is empty and you got enough resources.
it will automatically wake up 5 seconds after one celebration in any village is finished.

kingbot.celebrate(villages=[0, 2, 4], interval=1000)

villages:
array of villages (starting at zero) in which the bot should start celebrations

interval: (optional -> default = 1000)
just a save interval for the bot to wake up and check wether it can start a celebration
it will automatically adjust this interval to wake up right after a celebration is finished

adventures

this enables auto sending the hero on adventures.
you hero won't die, because they will only start when the hero is above x hp.

kingbot.start_adventures(interval=500, health=35)

interval: (optional -> default = 100)
time in seconds the hero thread will sleep until it checks for a new adventure again

health: (optional -> default = 50)
minimum health (in percent) of hero to start an adventure

dodge incoming attacks

since everybody hates to get attacked at night, the bot is able do dodge incoming attacks.
it will send your units to a given village for raid. make sure the village is inactive and valid.

the bot will wake up 10 minutes before the attack lands, so take a target which is at least 5:01 minutes away. (7:00 if you got a map and also send your hero)
use this method for every village you want to save.

kingbot.dodge_attack(village=0, units=[1, 0, 3], target=[1, 1], save_resources=True, units_train=[2, 4])

village:
index of village which the bot is going to check (starting at 0)

units:
array of unit indexes which are going to be saved (starting at 0)
insert -1 (units=[-1]) to save all available units in this village

target:
first index is the x-coordinate and second for the y-coordinate of the village the bot will send the units for a robbery

save_resources:
True if you want to save the resources and NPC it for training troops.
attention! this feature will consume your gold, please consider it.

units_train:
array of unit indexes which are going to be trained (starting at 1)

upgrade units in smithy

kingbot.upgrade_units_smithy(village=0, units=[21, 22])

village:
index of village (starting at 0)

units:
list of units you want to upgrade
first one with highest priority, last one with lowest

roman teuton gaul
1: legionnaire 11: clubswinger 21: phalanx
2: praetorian 12: spearfighter 22: swordsman
3: imperian 13: axefighter 23: pathfinder
4: equites legati 14: scout 24: theutates thunder
5: equites imperatoris 15: paladin 25: druidrider
6: equites caesaris 16: teutonic knight 26: headuan
7: battering ram 17: ram 27: ram
8: fire catapult 18: catapult 28: trebuchet
9: senator 19: chief 29: chieftain
10: settler 20: settler 30: settler

the bot checks if it can upgrade given units in given order. first it checks swordsman in this example and if they are not available or maxed out, it will try to upgrade phalax again.
you can increase the list as long as you want to.

the bot can't switch smithy pages for now, so make sure the window is big enough to cover 8 slots.
By default this should be the case, otherwise it will just cover the 4 slots on the front for now.

sleeping time will be the time the academy needs to finish the current research, so the bot won't wake up unnecessarily in the given interval.

upgrade resource fields / buildings

this function will construct and upgrade building as well as upgrade resources. finish 5 mins earlier is enable by default. this function will upgrade/construct based on json file that contains queue for upgrade/construct building. the json file can be edit while this function running, so didn't need to restart the function if you want add new queue to json file.

the json file have strict structure that need to be fulfilled if you want to use this function. this is an example of queue on json file:

{"queues":[
    {
        "queueLocation": "Village",
        "queueType": "Construct",
        "queueBuilding": "Bakery"
    }
    {
        "queueLocation": "Resources",
        "queueBuilding": "buildingLocation9"
    }
]}

queueLocation: there is 2 values for this keyword, Village and Resources.(case sensitive)

  • choose Village if you want to Upgrade or Construct building.
  • choose Resources when you want to upgrade resources.

queueType: there is 2 values for this keyword, Construct and Upgrade.(case sensitive)

  • choose Construct for constructing building.
  • choose Upgrade for upgrading building.

queueBuilding: this keyword filled with building name. if you want to upgrade resources, it point to slot id of resources that you want to upgrade.(case sensitive) on the picture below you can see all field slot id's for your reference when upgrading resources. these stay the same no matter what kind of village you have (even in 15er crop villages).

there is an example json file in assets folder that contain queue for your reference. there is also building.json file that contains building name for your reference.

kingbot.start_building(village=2, file_name='village_2.json', interval=1800)

village:
index of the village the slot should be upgraded in (starting at 0)

file_name:
json file that contain queue

interval: (optional -> default = 1800) interval for checking queue

attention! this feature can only be used in international gameworld

resource-fields

robber hideouts

the bot will check for robber hideouts and it will send your units to attack them, it will retry with the same hideout until its destroyed, and then it will move on to the next and so on.

the bot will not perform the attack if the troops are moving, either returning or leaving the village, and thus avoid repeating unnecessary attacks.

kingbot.robber_hideout(village=0, units={10:1, 4:100, 2:-1}, interval=600,)

village:
index of village from where the bot will attack the robbers (starting at 0)

units:
dictionary of units you want to send to the robber hideouts (starting at 0) the format of the units are expressed as a pair: {: } insert -1 (units={-1}) to send all available units in this village hero is "10:1"

roman teuton gaul
0: legionnaire 0: clubswinger 0: phalanx
1: praetorian 1: spearfighter 1: swordsman
2: imperian 2: axefighter 2: pathfinder
3: equites legati 3: scout 3: theutates thunder
4: equites imperatoris 4: paladin 4: druidrider
5: equites caesaris 5: teutonic knight 5: headuan
6: battering ram 6: ram 6: ram
7: fire catapult 7: catapult 7: trebuchet
8: senator 8: chief 8: chieftain
9: settler 9: settler 9: settler

ex: as roman send hero, 100 equites imperatoris and all imperian (units={10:1, 4:100, 2:-1})

interval: (optional -> default = 600) interval for checking robber hideouts

robber camps

the bot will check for robber camps and will send the specified units to attack all the camps at once while there are units available, as well as avoid attacking those already attacked before.

kingbot.robber_camp(village=0, units={10:1, 0:300}, interval=600,)

village:
index of village from where the bot will attack the robber camps (starting at 0)

units:
dictionary of units you want to send to the robber camps (starting at 0) the format of the units are expressed as a pair: {: } insert -1 (units={-1}) to send all available units in this village hero is "10:1" ex: as teuton send hero and 300 clubswinger (units={10:1, 0:300})

interval: (optional -> default = 600) interval for checking robber camps

train troops

the bot will train new troops every time interval, if more than one type of unit is specified, the bot will divide the resources by each type of units and try to train as much as possible of each.

kingbot.train_troops(village=0, units=[1, 2], interval=600)

village:
index of village which the bot is going to train troops (starting at 0)

units:
list of units you want to train

roman teuton gaul
1: legionnaire 11: clubswinger 21: phalanx
2: praetorian 12: spearfighter 22: swordsman
3: imperian 13: axefighter 23: pathfinder
4: equites legati 14: scout 24: theutates thunder
5: equites imperatoris 15: paladin 25: druidrider
6: equites caesaris 16: teutonic knight 26: headuan
7: battering ram 17: ram 27: ram
8: fire catapult 18: catapult 28: trebuchet
9: senator 19: chief 29: chieftain
10: settler 20: settler 30: settler

interval: (optional -> default = 600) interval to train troops

start options

just an overview. for details check each topic.

short long arguments description
-e --email your_email optional for login
-p --password your_password optional for login
-w --gameworld your_gameworld optional for login
-m - - login manually
-h - - no browser window
-r - - connect to last session

provide credentials

$ python start.py -e email@test.de -p your_password -w your_gameworld
$ python start.py --email email@test.de --password your_password --gameworld your_gameworld

if you don't want to store your credentials into a file, just provide them via arguments like this.
it's also possible to login manually if you dont want to provide your login credentials at all. see below: login manually

all of these options are optional, you can always provice some via code, and some via start options, that's up to you.

headless browsing

$ python start.py -h

if you don't wont a browser window to pop up, or using the script on a dedicated server with no gui, it is possible to run the script in headless mode.
the console window will inform you about important actions the bot will do.

login manually

$ python start.py -m 120

if you don't trust my program, even if it' open source, you can login manually and don't even type your email or password anywhere in my script.
the bot will open the main page of travian kingdoms.
it will now wait 120 seconds (given time via argument) for you to log into your account.
after you are logged in, just open the gameworld you want your bot to run in.
if you are finished, just wait for the timer to end, so the bot can do its work.

note: this is not possible in headless mode!

remote browser

$ python start.py -r

if the script exists because of an exception, it's possible to re-use the browser session so you don't have to go through the whole login process again.
just don't exit the browser window and make sure to remove the functions in the script, which the bot already completed in last session.

note: debug mode must be enabled!

proxy

proxy = '127.0.0.1:1234'

if you want to surf the web via proxy, just insert it in start.py. this is also possible in headless mode.
if the proxy is set to '', it's going to be disabled. it's also disabled by default.

faq

can i play the game while the bot is running?
yes. just open a new browser window and leave the bot window in the background. login to your gameworld and keep playing.
one instance doesn't effect another browser instance. you can also start your script without a browser window.

can i get banned for using the bot?
yes, but the chances are below 1%. it's nearly impossible to detect this bot, because it clicks all buttons just like a human would do.
also there is browser and sleeping time delay, so they can't event check if the interval is always the same.

my internet is really slow. the bot is too fast and can't find elements!
settings.browser_speed = 1.0 -> just increase this value. it will adjust all sleep timers.
you will find that value in start.py file.

how to contribute

you are not quite sure if you are able to contribute ? contact me (: !
i love to teach people who are interested in learning.

code style

  • type definitions at least for method signatures
  • do comments
  • keep your code seperated in files

workflow

  • take an issue or a personal idea to implement
  • fork the repository
  • start scripting
  • make a pull request

nice to know

  • store your login credentials in ./assets/credentials.txt -> ignored by git
    • gameworld;your_email;your_password
  • write your testscript as test_start.py -> ignored by git
  • run mypy for typechecking mypy start.py --ignore-missing-imports
  • set debug flag to True -> kingbot = kingbot(..., debug=True)
    • if your script executes with and error resume your session with python start.py -r

changelog

view changelog


we love lowercase