2022-07-04 10:44:45 +03:00

154 lines
5.5 KiB
Python

""" eBot
Copyright (C) 2022 Eriks K
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import copy
import os
import random
import sys
from datetime import timedelta
from typing import Dict, List, Union
import httpx
import sentry_sdk
from erepublik import Citizen, classes, utils
from ebot import __version__
from ebot.helpers import BotRestart, BotStop
from ebot.player import Player
from ebot.utils import _norm
VERSION = __version__
EVERSION = utils.VERSION
def main(config: Dict[str, Union[int, bool, str, List[str], Dict[str, Union[str, int]]]]):
player = Player("", "", False)
try: # If errors before player is initialized
while True:
has_dump = os.path.isfile("Player__dump.json")
if has_dump:
player = Player.load_from_dump("Player__dump.json")
else:
player = Player(email=config["email"], password=config["password"], auto_login=False)
player.setup_citizen(config)
player.login()
if player.logged_in:
sentry_sdk.set_user(dict(id=player.details.citizen_id, username=player.name, email=player.config.email))
try:
import setproctitle
setproctitle.setproctitle(f"eBot - {player}")
except ImportError:
pass
break
else:
utils.silent_sleep(2)
while True:
try:
player.update_all()
if not player.restricted_ip:
player.dump_instance()
break
except Exception as e: # noqa
player.report_error(f"Error updating all data on initial update {e}")
utils.silent_sleep(2)
player.write_log(
f"View Your stats at:\n"
f"'https://erep.lv/player/{player.name.replace(' ', '%20')}'\n"
f"Your password is '{player.reporter.key}'"
)
# if player.reporter.allowed:
report = copy.deepcopy(config)
report.pop("email", None)
report.pop("password", None)
report.update(VERSION=VERSION, eRepublik_version=EVERSION)
player.reporter.report_action("ACTIVE_CONFIG", json_val=report)
player.setup_tasks(config)
_run_main_loop(player)
player.set_locks()
player.logger.warning("Too many errors.")
except BotStop as bs:
raise bs
except BotRestart:
pass
except httpx.ConnectError as conn_err:
raise conn_err
except Exception as e: # noqa
if isinstance(player, Citizen):
name = player.name
elif config.get("email", None):
name = config["email"]
else:
name = "Uninitialized"
sentry_sdk.capture_exception(e)
player.report_error(
f"Fatal error. {e}", extra=dict(player_name=name, ebot_version=VERSION, erep_version=EVERSION)
)
finally:
if isinstance(player, Citizen):
player.set_locks()
def _run_main_loop(player: Player):
error_count = 0
while error_count < 3 and not player.stop_threads.is_set():
try:
player.update_all()
player.do_tasks()
next_task = player.get_next_task()
player.travel_to_residence()
random_seconds = random.randint(0, 121) if player.tasks.get_default("random_sleep", True) else 0
sleep_seconds = int(utils.get_sleep_seconds(next_task.time))
if sleep_seconds <= 0:
player.write_warning(f"Loop detected! Offending task: '{next_task.name}'")
next_time = _norm(next_task.time + timedelta(seconds=random_seconds)).strftime("%F %T")
tasks = player.tasks.as_dict["tasks"]
player.write_log("My next Tasks and there time:\n" + "\n".join((str(t) for t in tasks)))
player.write_log(
f"Sleeping until (eRep): {next_time} " f"(sleeping for {sleep_seconds}s + random {random_seconds}s)"
)
seconds_to_sleep = sleep_seconds + random_seconds
player.stop_threads.wait(seconds_to_sleep)
except (classes.ErepublikNetworkException, httpx.ConnectError) as exc:
sentry_sdk.capture_exception(exc)
player.write_warning("Network ERROR detected. Sleeping for 1min...")
player.sleep(60)
except BotRestart:
player.set_locks()
return
except classes.ErepublikException as exc:
sentry_sdk.capture_exception(exc)
player.report_error(f"Known error detected! {exc}")
except (KeyboardInterrupt, BotStop):
player.set_locks()
sys.exit(0)
except Exception as exc:
sentry_sdk.capture_exception(exc)
player.report_error(
f"Unknown error! {exc}",
extra=dict(player_name=player.name, ebot_version=VERSION, erep_version=EVERSION),
)
error_count += 1
if error_count < 3:
player.sleep(60)