241 lines
8.2 KiB
Python
241 lines
8.2 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 json
|
|
import logging
|
|
import os
|
|
import platform
|
|
import re
|
|
import subprocess
|
|
from datetime import datetime
|
|
from typing import Any, Dict, List, Union
|
|
|
|
from erepublik import constants, utils
|
|
|
|
logger = logging.getLogger("Player")
|
|
|
|
|
|
def _norm(dt: datetime) -> datetime:
|
|
return constants.erep_tz.normalize(dt)
|
|
|
|
|
|
def parse_input(msg: str) -> bool:
|
|
msg += " (y|n):"
|
|
data = None
|
|
while data not in ["", "y", "Y", "n", "N"]:
|
|
try:
|
|
data = input(msg)
|
|
except EOFError:
|
|
data = "n"
|
|
|
|
return data in ["", "y", "Y"]
|
|
|
|
|
|
def get_config(
|
|
config_location: str = "config.json",
|
|
) -> Dict[str, Union[str, int, bool, List[str], Dict[str, Union[int, str, bool]]]]:
|
|
CONFIG = {}
|
|
if os.path.isfile(config_location):
|
|
with open(config_location, "r") as f:
|
|
CONFIG.update(json.load(f))
|
|
|
|
logger.info("Config file found. Checking...")
|
|
should_save = parse_config(CONFIG)
|
|
else:
|
|
should_save = parse_config(CONFIG)
|
|
if should_save:
|
|
with open(config_location, "w") as f:
|
|
json.dump(CONFIG, f, indent=True)
|
|
return CONFIG
|
|
|
|
|
|
def parse_config(config: Dict[str, Any]) -> bool:
|
|
"""Parse configuration dictionary and fill any missing keys.
|
|
|
|
:type config: dict
|
|
:rtype: bool
|
|
:param config: None or dict with configs
|
|
:return: boolean if passed dict had to be changed
|
|
"""
|
|
changed = False
|
|
if not config.get("email"):
|
|
config["email"] = input("Player email: ")
|
|
changed = True
|
|
|
|
if not config.get("password"):
|
|
config["password"] = input("Player password: ")
|
|
changed = True
|
|
|
|
if "employ" in config:
|
|
config["employees"] = config.pop("employ")
|
|
changed = True
|
|
|
|
_basic_prompt_dict = dict(
|
|
work="Should I work",
|
|
train="Should I train",
|
|
ot="Should I work overtime",
|
|
wam="Should I WAM",
|
|
employees="Should I employ employees",
|
|
)
|
|
|
|
for key, prompt in _basic_prompt_dict.items():
|
|
if key not in config:
|
|
config[key] = parse_input(prompt)
|
|
changed = True
|
|
|
|
if config["wam"] or config["employees"]:
|
|
if "auto_sell" not in config or not isinstance(config["auto_sell"], list):
|
|
config["auto_sell"] = []
|
|
changed = True
|
|
if parse_input("Should I auto sell produced products"):
|
|
if parse_input("Should I auto sell final products"):
|
|
_final_prompt_dict = dict(
|
|
food="Should I auto sell Food products",
|
|
weapon="Should I auto sell Weapon products",
|
|
house="Should I auto sell House products",
|
|
aircraft="Should I auto sell Aircraft products",
|
|
)
|
|
for key, prompt in _final_prompt_dict.items():
|
|
if parse_input(prompt):
|
|
config["auto_sell"].append(key)
|
|
if parse_input("Should I auto sell raw products"):
|
|
_raw_prompt_dict = dict(
|
|
foodRaw="Should I auto sell Food raw",
|
|
weaponRaw="Should I auto sell Weapon raw",
|
|
houseRaw="Should I auto sell House raw",
|
|
airplaneRaw="Should I auto sell Aircraft raw",
|
|
)
|
|
for key, prompt in _raw_prompt_dict.items():
|
|
if parse_input(prompt):
|
|
config["auto_sell"].append(key)
|
|
if config["auto_sell"]:
|
|
if "auto_sell_all" not in config:
|
|
print("When selling produced items should I also sell items already in inventory?")
|
|
config["auto_sell_all"] = parse_input("Y - sell all, N - only just produced")
|
|
changed = True
|
|
else:
|
|
config["auto_sell_all"] = False
|
|
|
|
if "auto_buy_raw" not in config:
|
|
config["auto_buy_raw"] = parse_input("Should I auto buy raw deficit at WAM or employ")
|
|
changed = True
|
|
else:
|
|
config["auto_sell"] = []
|
|
config["auto_sell_all"] = False
|
|
config["auto_buy_raw"] = False
|
|
|
|
if "fight" not in config:
|
|
config["fight"] = False # parse_input("Should I fight")
|
|
changed = True
|
|
|
|
if config.get("fight"):
|
|
_fight_prompt_dict = dict(
|
|
air="Should I fight in AIR",
|
|
ground="Should I fight in GROUND",
|
|
all_in="When full energy should i go all in\n Y - all in, N - 1h worth of energy",
|
|
next_energy="Should I fight when next WC +1 energy is reachable",
|
|
boosters="Should I use +50% dmg boosters, when fighting on ground",
|
|
travel_to_fight="Should I travel to fight",
|
|
epic_hunt="Should I check for epic battles",
|
|
rw_def_side="Should I fight on defenders side in RWs",
|
|
continuous_fighting="If already fought in any battle, \nshould I continue to fight all FF in that battle",
|
|
maverick="If MaverickPack is active, \nshould I try to fight in non-native divisions?",
|
|
)
|
|
|
|
for key, prompt in _fight_prompt_dict.items():
|
|
if key not in config:
|
|
config[key] = parse_input(prompt)
|
|
changed = True
|
|
|
|
if not config["epic_hunt"]:
|
|
config["epic_hunt_ebs"] = False
|
|
elif "epic_hunt_ebs" not in config:
|
|
config["epic_hunt_ebs"] = parse_input("Should I eat EBs when fighting in epic battle")
|
|
changed = True
|
|
|
|
else:
|
|
config["air"] = False
|
|
config["ground"] = False
|
|
config["all_in"] = False
|
|
config["next_energy"] = False
|
|
config["boosters"] = False
|
|
config["travel_to_fight"] = False
|
|
config["epic_hunt"] = False
|
|
config["epic_hunt_ebs"] = False
|
|
config["rw_def_side"] = False
|
|
config["continuous_fighting"] = False
|
|
|
|
_other_prompt_dict = dict(
|
|
spin_wheel_of_fortune="Should I auto spin WheelOfFortune for 10% cc amount",
|
|
congress="Candidate for congress",
|
|
party_president="Candidate for party presidency",
|
|
debug="Should I generate debug files",
|
|
random_sleep="Should I add random amount (0-120sec) to sleep time",
|
|
buy_gold="Should I auto buy 10g every day",
|
|
interactive="Should I print output to console?",
|
|
telegram="Should I send notifications through Telegram",
|
|
)
|
|
|
|
for key, prompt in _other_prompt_dict.items():
|
|
if key not in config:
|
|
config[key] = parse_input(prompt)
|
|
changed = True
|
|
|
|
if "telegram_chat_id" not in config and config["telegram"]:
|
|
config["telegram_chat_id"] = ""
|
|
|
|
if "telegram_token" not in config and config["telegram"]:
|
|
config["telegram_token"] = ""
|
|
|
|
if "proxy" not in config:
|
|
config["_proxy"] = {
|
|
"kind": "socks or http",
|
|
"host": "localhost",
|
|
"port": 8080,
|
|
"username": "optional",
|
|
"password": "optional",
|
|
}
|
|
changed = True
|
|
|
|
return changed
|
|
|
|
|
|
def jsonify(data) -> Any:
|
|
return utils.json_loads(dict_to_json(data))
|
|
|
|
|
|
def dict_to_json(data) -> str:
|
|
return utils.json_dumps(data)
|
|
|
|
|
|
def pid_alive(pid: int) -> bool:
|
|
"""Check For whether a pid is alive"""
|
|
|
|
system = platform.uname().system
|
|
if re.search(r"Linux|Darwin", system, re.IGNORECASE):
|
|
try:
|
|
os.kill(pid, 0)
|
|
except OSError:
|
|
return False
|
|
else:
|
|
return True
|
|
elif re.search("Windows", system, re.IGNORECASE):
|
|
out = subprocess.check_output(["tasklist", "/fi", f"PID eq {pid}"]).strip()
|
|
return bool(re.search(b"No tasks", out, re.IGNORECASE))
|
|
else:
|
|
return False
|
|
# raise RuntimeError(f"unsupported system={system}")
|