154 lines
5.5 KiB
Python
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)
|