107 lines
4.7 KiB
Python
107 lines
4.7 KiB
Python
import threading
|
|
from datetime import timedelta
|
|
|
|
from erepublik import Citizen, utils
|
|
|
|
CONFIG = {
|
|
'email': 'player@email.com',
|
|
'password': 'Pa$5w0rd!',
|
|
'interactive': True,
|
|
'fight': True,
|
|
'debug': True,
|
|
'battle_launcher': {
|
|
# War id: {auto_attack: bool (attack asap when region is available), regions: [region_ids allowed to attack]}
|
|
121672: {"auto_attack": False, "regions": [661]},
|
|
125530: {"auto_attack": False, "regions": [259]},
|
|
125226: {"auto_attack": True, "regions": [549]},
|
|
124559: {"auto_attack": True, "regions": [176]}
|
|
}
|
|
}
|
|
|
|
|
|
def _battle_launcher(player: Citizen):
|
|
"""Launch battles. Check every 5th minute (0,5,10...45,50,55) if any battle could be started on specified regions
|
|
and after launching wait for 90 minutes before starting next attack so that all battles aren't launched at the same
|
|
time. If player is allowed to fight, do 100 hits on the first round in players division.
|
|
|
|
:param player: Logged in Citizen instance
|
|
:type player: Citizen
|
|
"""
|
|
global CONFIG
|
|
finished_war_ids = {*[]}
|
|
war_data = CONFIG.get('battle_launcher', {})
|
|
war_ids = {int(war_id) for war_id in war_data.keys()}
|
|
next_attack_time = player.now
|
|
next_attack_time = next_attack_time.replace(minute=next_attack_time.minute // 5 * 5, second=0)
|
|
while not player.stop_threads.is_set():
|
|
try:
|
|
attacked = False
|
|
player.update_war_info()
|
|
running_wars = {b.war_id for b in player.all_battles.values()}
|
|
for war_id in war_ids - finished_war_ids - running_wars:
|
|
war = war_data[war_id]
|
|
war_regions = set(war.get('regions'))
|
|
auto_attack = war.get('auto_attack')
|
|
|
|
status = player.get_war_status(war_id)
|
|
if status.get('ended', False):
|
|
CONFIG['battle_launcher'].pop(war_id, None)
|
|
finished_war_ids.add(war_id)
|
|
continue
|
|
elif not status.get('can_attack'):
|
|
continue
|
|
|
|
if auto_attack or (player.now.hour > 20 or player.now.hour < 2):
|
|
for reg in war_regions:
|
|
if attacked:
|
|
break
|
|
if reg in status.get('regions', {}).keys():
|
|
player.launch_attack(war_id, reg, status.get('regions', {}).get(reg))
|
|
attacked = True
|
|
hits = 100
|
|
if player.energy.food_fights >= hits and player.config.fight:
|
|
for _ in range(120):
|
|
player.update_war_info()
|
|
battle_id = player.get_war_status(war_id).get("battle_id")
|
|
if battle_id is not None and battle_id in player.all_battles:
|
|
battle = player.all_battles.get(battle_id)
|
|
for division in battle.div.values():
|
|
if division.div == player.division:
|
|
div = division
|
|
break
|
|
else:
|
|
player.report_error("Players division not found in the first round!")
|
|
break
|
|
player.fight(battle, div, battle.invader, hits)
|
|
break
|
|
player.sleep(1)
|
|
if attacked:
|
|
break
|
|
if attacked:
|
|
break
|
|
war_ids -= finished_war_ids
|
|
if attacked:
|
|
next_attack_time = utils.good_timedelta(next_attack_time, timedelta(hours=1, minutes=30))
|
|
else:
|
|
next_attack_time = utils.good_timedelta(next_attack_time, timedelta(minutes=5))
|
|
player.stop_threads.wait(utils.get_sleep_seconds(next_attack_time))
|
|
except Exception as e:
|
|
player.report_error(f"Task battle launcher ran into error {e}")
|
|
|
|
|
|
# noinspection DuplicatedCode
|
|
def main():
|
|
player = Citizen(email=CONFIG['email'], password=CONFIG['password'], auto_login=False)
|
|
player.config.interactive = CONFIG['interactive']
|
|
player.config.fight = CONFIG['fight']
|
|
player.set_debug(CONFIG.get('debug', False))
|
|
player.login()
|
|
if CONFIG.get('battle_launcher'):
|
|
name = "{}-battle_launcher-{}".format(player.name, threading.active_count() - 1)
|
|
state_thread = threading.Thread(target=_battle_launcher, args=(player,), name=name)
|
|
state_thread.start()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|