erepublik-ebot/ebot/utils.py
2022-07-04 10:44:45 +03:00

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}")