diff --git a/erepublik_script/__init__.py b/erepublik_script/__init__.py index fd19371..5bd7b28 100644 --- a/erepublik_script/__init__.py +++ b/erepublik_script/__init__.py @@ -5,412 +5,8 @@ __author__ = """Eriks Karls""" __email__ = 'eriks@72.lv' __version__ = '0.1.0' - -import json -import os -import random -import sys -import threading -from collections import defaultdict -from datetime import timedelta -from typing import List, Tuple +__all__ = ["Citizen"] from erepublik_script import classes, utils from erepublik_script.citizen import Citizen -__all__ = ["Citizen"] - -INTERACTIVE = True -CONFIG = defaultdict(bool) - - -def main(): - player = None - try: # If errors before player is initialized - while True: - player = Citizen(email=CONFIG['email'], password=CONFIG['password']) - if player.logged_in: - break - utils.silent_sleep(2) - player.config.work = CONFIG['work'] - player.config.train = CONFIG['train'] - player.config.ot = CONFIG['ot'] - player.config.wam = bool(CONFIG['wam']) - player.config.employees = bool(CONFIG['employ']) - player.config.auto_sell = CONFIG.get('auto_sell', []) - player.config.auto_sell_all = CONFIG.get('auto_sell_all', False) - player.config.auto_buy_raw = CONFIG.get('auto_buy_raw', False) - player.config.force_wam = CONFIG.get('force_wam', False) - player.config.fight = CONFIG['fight'] - player.config.air = CONFIG['air'] - player.config.ground = CONFIG['ground'] - player.config.all_in = CONFIG['all_in'] - player.config.next_energy = CONFIG['next_energy'] - player.config.boosters = CONFIG['boosters'] - player.config.travel_to_fight = CONFIG['travel_to_fight'] - player.config.always_travel = CONFIG.get('always_travel', False) - player.config.epic_hunt = CONFIG['epic_hunt'] - player.config.epic_hunt_ebs = CONFIG['epic_hunt_ebs'] - player.config.rw_def_side = CONFIG['rw_def_side'] - player.config.random_sleep = CONFIG['random_sleep'] - player.config.continuous_fighting = CONFIG['continuous_fighting'] - player.config.interactive = CONFIG['interactive'] - player.reporter.allowed = not CONFIG.get('reporting_is_not_allowed') - - player.set_debug(CONFIG.get('debug', False)) - while True: - try: - player.update_all() - break - except: - utils.silent_sleep(2) - - now = utils.now() - dt_max = now.replace(year=9999) - tasks = { - 'eat': now, - } - wam_hour = employ_hour = 14 - if player.config.work: - tasks.update({'work': now}) - if player.config.train: - tasks.update({'train': now}) - if player.config.ot: - tasks.update({'ot': now}) - if player.config.fight: - tasks.update({'fight': now}) - if player.config.wam: - wam_hour = 14 - if not isinstance(CONFIG['wam'], bool): - try: - wam_hour = abs(int(CONFIG['wam'])) % 24 - except ValueError: - pass - tasks.update({'wam': now.replace(hour=wam_hour, minute=0, second=0, microsecond=0)}) - if player.config.employees: - employ_hour = 8 - if not isinstance(CONFIG['employ'], bool): - try: - employ_hour = abs(int(CONFIG['employ'])) % 24 - except ValueError: - pass - tasks.update({'employ': now.replace(hour=employ_hour, minute=0, second=0, microsecond=0)}) - - if player.config.epic_hunt: - tasks['epic_hunt'] = now - - if CONFIG.get("renew_houses", True): - tasks['renew_houses'] = now - - if CONFIG.get('start_battles'): - """ {'start_battle': {war_id: {'regions': [region_id, ], - 'timing': ['at', 'hh:mm' | 'before', 'hh:mm' (before autoattack) | - 'auto' (after round for citizenship country's oldest battle or at 00:00) - 'rw', (after first round of RW if you are occupying)]}} """ - player.allowed_battles = CONFIG.get('start_battles', dict()) - raise classes.ErepublikException("Battle starting is not implemented") - - if player.reporter.allowed: - report = dict(CONFIG) - report.pop("email", None) - report.pop("password", None) - report.update( - VERSION=utils.VERSION, - COMMIT_ID=utils.COMMIT_ID - ) - player.reporter.report_action("ACTIVE_CONFIG", json_val=report) - # -1 because main thread is counted in - name = "{}-state_updater-{}".format(player.name, threading.active_count() - 1) - state_thread = threading.Thread(target=player.state_update_repeater, name=name) - state_thread.start() - - if CONFIG.get("congress", True): - tasks['congress'] = now.replace(hour=1, minute=30, second=0) - - if CONFIG.get("party_president", False): - tasks['party_president'] = now.replace(hour=1, minute=30, second=0) - - contribute_cc = int(CONFIG.get("contribute_cc", 0)) - if contribute_cc: - tasks['contribute_cc'] = now.replace(hour=2, minute=0, second=0) - - if CONFIG.get("gold_buy"): - tasks['gold_buy'] = now.replace(hour=23, minute=57, second=0, microsecond=0) - - error_count = 0 - while error_count < 3: - try: - now = utils.now() - player.update_all() - if tasks.get('work', dt_max) <= now: - player.write_log("Doing task: work") - player.update_citizen_info() - player.work() - if player.config.ot: - tasks['ot'] = now - player.collect_daily_task() - next_time = now.replace(hour=0, minute=0, second=0) + timedelta(days=1) - tasks.update({'work': next_time}) - - if tasks.get('train', dt_max) <= now: - player.write_log("Doing task: train") - player.update_citizen_info() - player.train() - player.collect_daily_task() - next_time = now.replace(hour=0, minute=0, second=0) + timedelta(days=1) - tasks.update({'train': next_time}) - - if tasks.get('wam', dt_max) <= now: - player.write_log("Doing task: Work as manager") - success = player.work_wam() - player.eat() - if success: - next_time = now.replace(hour=wam_hour, minute=0, second=0, microsecond=0) + timedelta(days=1) - else: - next_time = now.replace(second=0, microsecond=0) + timedelta(minutes=30) - - tasks.update({'wam': next_time}) - - if tasks.get('eat', dt_max) <= now: - player.write_log("Doing task: eat") - player.eat() - - if player.energy.food_fights > player.energy.limit // 10: - next_minutes = 12 - else: - next_minutes = (player.energy.limit - 5 * player.energy.interval) // player.energy.interval * 6 - - next_time = player.energy.reference_time + timedelta(minutes=next_minutes) - tasks.update({'eat': next_time}) - - if tasks.get('fight', dt_max) <= now or player.energy.is_energy_full: - fight_energy_debug_log: List[Tuple[int, str]] = [] - player.write_log("Doing task: fight") - player.write_log(player.health_info) - - if player.should_fight(): - player.find_battle_and_fight() - else: - player.collect_weekly_reward() - energy = classes.EnergyToFight(player.details.xp_till_level_up * 10 - player.energy.limit + 50) - fight_energy_debug_log.append(( - energy.i, - f"Levelup reachable {player.details.xp_till_level_up} * 10 - {player.energy.limit} + 50" - )) - - # Do levelup - energy.check(player.details.xp_till_level_up * 10 + 50) - fight_energy_debug_log.append(( - energy.i, f"Levelup {player.details.xp_till_level_up} * 10 + 50" - )) - - # if levelup is close stop queueing other fighting - if not player.is_levelup_close: - - # Obligatory need 75pp - if player.details.pp < 75: - energy.check(75 - player.details.pp) - fight_energy_debug_log.append((energy.i, f"Obligatory need 75pp: 75 - {player.details.pp}")) - - if player.config.continuous_fighting and player.has_battle_contribution: - energy.check(player.energy.interval) - fight_energy_debug_log.append((energy.i, f"continuous_fighting: {player.energy.interval}")) - - # All-in - if player.config.all_in: - energy.check(player.energy.limit * 2 - 3 * player.energy.interval) - fight_energy_debug_log.append(( - energy.i, f"All-in: {player.energy.limit} * 2 - 3 * {player.energy.interval}" - )) - elif player.energy.limit * 2 - 3 * player.energy.interval >= player.energy.recovered: - # 1h worth of energy - energy.check(player.energy.limit * 2 - 3 * player.energy.interval) - fight_energy_debug_log.append( - (energy.i, f"1h worth of energy: {player.energy.interval} * 10" - )) - - # All-in for AIR battles - if all([player.config.air, player.config.all_in, - player.energy.available >= player.energy.limit]): - energy.check(player.energy.limit) - fight_energy_debug_log.append(( - energy.i, f"All-in for AIR battles: {player.energy.limit}" - )) - - # Get to next Energy +1 - if player.next_reachable_energy and player.config.next_energy: - energy.check(player.next_reachable_energy * 10) - fight_energy_debug_log.append(( - energy.i, f"Get to next Energy +1: {player.next_reachable_energy} * 10" - )) - - energy = energy.i - player.energy.available - next_minutes = max([6, abs(energy) // player.energy.interval * 6]) - # utils.write_silent_log("\n".join([f"{energy} {info}" for energy, info in fight_energy_debug_log])) - next_time = player.energy.reference_time + timedelta(minutes=next_minutes) - tasks.update({'fight': next_time}) - - if tasks.get('ot', dt_max) <= now: - player.write_log("Doing task: ot") - if now > player.my_companies.next_ot_time: - player.work_ot() - next_time = now + timedelta(minutes=60) - else: - next_time = player.my_companies.next_ot_time - tasks.update({'ot': next_time}) - - if tasks.get('employ', dt_max) <= now: - player.write_log("Doing task: Employee work") - next_time = utils.now().replace(hour=employ_hour, minute=0, second=0) + timedelta(days=1) - next_time = next_time if player.work_employees() else tasks.get('employ') + timedelta(minutes=30) - tasks.update({'employ': next_time}) - - if tasks.get('epic_hunt', dt_max) <= now: - player.write_log("Doing task: EPIC check") - player.check_epic_battles() - if player.active_fs: - next_time = now + timedelta(minutes=1) - else: - next_time = tasks.get('eat') - tasks.update({'epic_hunt': next_time}) - - if tasks.get('gold_buy', dt_max) <= now: - player.write_log("Doing task: auto buy 10g") - for offer in player.get_monetary_offers(): - if offer['amount'] >= 10 and player.details.cc >= 20 * offer["price"]: - # TODO: check allowed amount to buy - if player.buy_monetary_market_offer(offer=offer['offer_id'], amount=10, currency=62): - break - - next_time = tasks.get('gold_buy') + timedelta(days=1) - tasks.update({'gold_buy': next_time}) - - if tasks.get('congress', dt_max) <= now: - if 1 <= now.day < 16: - next_time = now.replace(day=16) - elif 16 <= now.day < 24: - player.write_log("Doing task: candidate for congress") - player.candidate_for_congress() - if not now.month == 12: - next_time = now.replace(month=now.month + 1, day=16) - else: - next_time = now.replace(year=now.year + 1, month=1, day=16) - else: - if not now.month == 12: - next_time = now.replace(month=now.month + 1, day=16) - else: - next_time = now.replace(year=now.year + 1, month=1, day=16) - tasks.update({'congress': next_time.replace(hour=1, minute=30, second=0, microsecond=0)}) - - if tasks.get('party_president', dt_max) <= now: - if not now.day == 15: - player.write_log("Doing task: candidate for party president") - player.candidate_for_party_presidency() - if not now.month == 12: - next_time = now.replace(month=now.month + 1) - else: - next_time = now.replace(year=now.year + 1, month=1) - else: - if not now.month == 12: - next_time = now.replace(month=now.month + 1) - else: - next_time = now.replace(year=now.year + 1, month=1) - tasks.update(party_president=next_time.replace(day=16, hour=0, minute=0, second=0, microsecond=0)) - - if tasks.get('contribute_cc', dt_max) <= now: - if not now.weekday(): - player.update_money() - cc = (player.details.cc // contribute_cc) * contribute_cc - player.write_log("Doing task: Contribute {}cc to Latvia".format(cc)) - player.contribute_cc_to_country(cc) - next_time = now + timedelta(days=7 - now.weekday()) - next_time = next_time.replace(hour=2, minute=0, second=0) - tasks.update({'contribute_cc': next_time}) - - if tasks.get('renew_houses', dt_max) <= now: - player.write_log("Doing task: Renew houses") - end_times = player.renew_houses() - if end_times: - tasks.update(renew_houses=min(end_times.values()) - timedelta(hours=24)) - else: - player.write_log("No houses found! Forcing q1 usage...") - end_times = player.buy_and_activate_house(1) - if not end_times: - tasks.update(renew_houses=now + timedelta(hours=6)) - else: - tasks.update(renew_houses=min(end_times.values()) - timedelta(hours=24)) - - closest_next_time = dt_max - next_tasks = [] - for task, next_time in sorted(tasks.items(), key=lambda s: s[1]): - next_tasks.append("{}: {}".format(next_time.strftime('%F %T'), task)) - if next_time < closest_next_time: - closest_next_time = next_time - random_seconds = random.randint(0, 121) if player.config.random_sleep else 0 - sleep_seconds = int(utils.get_sleep_seconds(closest_next_time)) - if sleep_seconds <= 0: - raise classes.ErepublikException(f"Loop detected! Offending task: '{next_tasks[0]}'") - closest_next_time += timedelta(seconds=random_seconds) - player.write_log("My next Tasks and there time:\n" + "\n".join(sorted(next_tasks))) - player.write_log("Sleeping until (eRep): {} (sleeping for {}s + random {}s)".format( - closest_next_time.strftime("%F %T"), sleep_seconds, random_seconds)) - seconds_to_sleep = sleep_seconds + random_seconds if sleep_seconds > 0 else 0 - player.sleep(seconds_to_sleep) - - except classes.ErepublikNetworkException: - player.write_log('Network ERROR detected. Sleeping for 1min...') - player.sleep(60) - except (KeyboardInterrupt, SystemExit): - sys.exit(1) - except classes.ErepublikException as e: - utils.process_error(f"Known error detected! {e}", player.name, sys.exc_info(), player, utils.COMMIT_ID) - except: - utils.process_error("Unknown error!", player.name, sys.exc_info(), player, utils.COMMIT_ID) - error_count += 1 - if error_count < 3: - player.sleep(60) - player.stop_threads.set() - player.write_log('Too many errors.') - except (KeyboardInterrupt, SystemExit): - sys.exit(1) - except classes.ErepublikException: - utils.process_error("[{}] Fatal error.".format(utils.COMMIT_ID), player.name, sys.exc_info(), player, - utils.COMMIT_ID) - except: - if isinstance(player, Citizen): - name = player.name - elif CONFIG.get('email', None): - name = CONFIG['email'] - else: - name = "Uninitialized" - utils.process_error("[{}] Fatal error.".format(utils.COMMIT_ID), name, sys.exc_info(), player, utils.COMMIT_ID) - sys.exit(1) - - -if __name__ == "__main__": - assert sys.version_info >= (3, 7, 1) - - write_log = utils.write_silent_log - - try: - with open('config.json', 'r') as f: - CONFIG = json.load(f) - - write_log('Config file found. Checking...') - CONFIG = utils.parse_config(CONFIG) - except: - CONFIG = utils.parse_config() - - with open('config.json', 'w') as f: - json.dump(CONFIG, f, indent=True, sort_keys=True) - if CONFIG['interactive']: - write_log = utils.write_interactive_log - else: - write_log = utils.write_silent_log - write_log('\nTo quit press [ctrl] + [c]', False) - os.chdir(os.path.dirname(os.path.realpath(__file__))) - write_log('Version: ' + utils.VERSION) - while True: - main() - write_log("Restarting after 1h") - utils.interactive_sleep(60 * 60)