Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
d5ed989e80 | |||
6fc24b8adf | |||
cf797f2f60 | |||
ad29045ace | |||
c919e46af5 | |||
644b4d70e1 | |||
6dbbd054ba | |||
0ee952e504 | |||
bb9b198a53 | |||
cb22e631ca | |||
c43e20c8f6 | |||
c8f41b97af | |||
d483bcbcb9 | |||
a316f277fb | |||
e8c81d17e6 |
6
Makefile
6
Makefile
@ -88,9 +88,3 @@ dist: clean ## builds source and wheel package
|
||||
|
||||
install: clean ## install the package to the active Python's site-packages
|
||||
python setup.py install
|
||||
|
||||
setcommit:
|
||||
bash set_commit_id.sh
|
||||
# commit=`git log -1 --pretty=format:%h`
|
||||
# sed -i.bak -E "s|COMMIT_ID = \".+\"|COMMIT_ID = \"$(commit)\"|g" erepublik/utils.py
|
||||
# mv erepublik/utils.py.bak erepublik/utils.py
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
__author__ = """Eriks Karls"""
|
||||
__email__ = 'eriks@72.lv'
|
||||
__version__ = '0.21.1'
|
||||
__version__ = '0.21.3'
|
||||
|
||||
from erepublik import classes, utils, constants
|
||||
from erepublik.citizen import Citizen
|
||||
|
@ -15,24 +15,26 @@ class SlowRequests(Session):
|
||||
timeout = datetime.timedelta(milliseconds=500)
|
||||
uas = [
|
||||
# Chrome
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36', # noqa
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36', # noqa
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36', # noqa
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36', # noqa
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36', # noqa
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.106 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
|
||||
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36',
|
||||
|
||||
# FireFox
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:76.0) Gecko/20100101 Firefox/76.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:75.0) Gecko/20100101 Firefox/75.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:73.0) Gecko/20100101 Firefox/73.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:83.0) Gecko/20100101 Firefox/83.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:82.0) Gecko/20100101 Firefox/82.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:81.0) Gecko/20100101 Firefox/81.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:79.0) Gecko/20100101 Firefox/79.0',
|
||||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:82.0) Gecko/20100101 Firefox/82.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:81.0) Gecko/20100101 Firefox/81.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:80.0) Gecko/20100101 Firefox/80.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:79.0) Gecko/20100101 Firefox/79.0',
|
||||
'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
|
||||
]
|
||||
debug = False
|
||||
|
||||
@ -433,7 +435,7 @@ class ErepublikMilitaryAPI(CitizenBaseAPI):
|
||||
|
||||
class ErepublikPoliticsAPI(CitizenBaseAPI):
|
||||
def _get_candidate_party(self, party_slug: str) -> Response:
|
||||
return self.post(f"{self.url}/candidate/{party_slug}")
|
||||
return self.get(f"{self.url}/candidate/{party_slug}")
|
||||
|
||||
def _get_main_party_members(self, party_id: int) -> Response:
|
||||
return self.get(f"{self.url}/main/party-members/{party_id}")
|
||||
@ -448,6 +450,13 @@ class ErepublikPoliticsAPI(CitizenBaseAPI):
|
||||
def _get_presidential_elections(self, country_id: int, timestamp: int) -> Response:
|
||||
return self.get(f"{self.url}/main/presidential-elections/{country_id}/{timestamp}")
|
||||
|
||||
def _post_propose_president_candidate(self, party_slug: str, citizen_id: int) -> Response:
|
||||
return self.post(f"{self.url}/propose-president-candidate/{party_slug}",
|
||||
data=dict(_token=self.token, citizen=citizen_id))
|
||||
|
||||
def _get_auto_propose_president_candidate(self, party_slug: str) -> Response:
|
||||
return self.get(f"{self.url}/auto-propose-president-candidate/{party_slug}")
|
||||
|
||||
|
||||
class ErepublikPresidentAPI(CitizenBaseAPI):
|
||||
def _post_wars_attack_region(self, war_id: int, region_id: int, region_name: str) -> Response:
|
||||
|
@ -393,7 +393,7 @@ class BaseCitizen(access_points.CitizenAPI):
|
||||
sleep(seconds)
|
||||
|
||||
def to_json(self, indent: bool = False) -> str:
|
||||
return utils.json.dumps(self, cls=classes.MyJSONEncoder, indent=4 if indent else None, sort_keys=True)
|
||||
return utils.json.dumps(self, cls=classes.MyJSONEncoder, indent=4 if indent else None)
|
||||
|
||||
def get_countries_with_regions(self) -> Set[constants.Country]:
|
||||
r_json = self._post_main_travel_data().json()
|
||||
@ -1314,9 +1314,6 @@ class CitizenMilitary(CitizenTravel):
|
||||
boosters: Dict[int, Dict[int, int]] = {100: {}, 50: {}}
|
||||
|
||||
def update_war_info(self):
|
||||
if not self.details.current_country:
|
||||
self.update_citizen_info()
|
||||
|
||||
if self.__last_war_update_data and self.__last_war_update_data.get('last_updated',
|
||||
0) + 30 > self.now.timestamp():
|
||||
r_json = self.__last_war_update_data
|
||||
@ -1341,7 +1338,10 @@ class CitizenMilitary(CitizenTravel):
|
||||
all_battles = {}
|
||||
for battle_data in r_json.get("battles", {}).values():
|
||||
all_battles[battle_data.get('id')] = classes.Battle(battle_data)
|
||||
old_all_battles = self.all_battles
|
||||
self.all_battles = all_battles
|
||||
for battle in old_all_battles.values():
|
||||
utils._clear_up_battle_memory(battle)
|
||||
|
||||
def get_battle_for_war(self, war_id: int) -> Optional[classes.Battle]:
|
||||
self.update_war_info()
|
||||
@ -1516,35 +1516,33 @@ class CitizenMilitary(CitizenTravel):
|
||||
ret_battles = ret_battles + cs_battles + deployed_battles + other_battles
|
||||
return ret_battles
|
||||
|
||||
def get_cheap_tp_divisions(self) -> Optional[classes.BattleDivision]:
|
||||
air_divs: List[Tuple[classes.BattleDivision, int]] = []
|
||||
ground_divs: List[Tuple[classes.BattleDivision, int]] = []
|
||||
def get_cheap_tp_divisions(self) -> Dict[str, List[Tuple[int, classes.BattleDivision]]]:
|
||||
air_divs: List[Tuple[int, classes.BattleDivision]] = []
|
||||
ground_divs: List[Tuple[int, classes.BattleDivision]] = []
|
||||
for battle in reversed(self.sorted_battles(True, True)):
|
||||
for division in battle.div.values():
|
||||
if not division.terrain:
|
||||
is_start_ok = utils.good_timedelta(division.battle.start, timedelta(minutes=-1)) < self.now
|
||||
if not division.terrain and is_start_ok and not division.div_end:
|
||||
if division.is_air and self.config.air:
|
||||
medal = self.get_battle_round_data(division)[
|
||||
self.details.citizenship == division.battle.defender.id]
|
||||
if not medal and division.battle.start:
|
||||
return division
|
||||
division_medals = self.get_battle_round_data(division)
|
||||
medal = division_medals[self.details.citizenship == division.battle.defender.country]
|
||||
if not medal:
|
||||
air_divs.append((0, division))
|
||||
else:
|
||||
air_divs.append((division, medal.get('1').get('raw_value')))
|
||||
elif self.config.ground:
|
||||
air_divs.append((medal.get('1').get('raw_value'), division))
|
||||
elif not division.is_air and self.config.ground:
|
||||
if not division.div == self.division and not self.maverick:
|
||||
continue
|
||||
division_medals = self.get_battle_round_data(division)
|
||||
medal = division_medals[self.details.citizenship == division.battle.defender.country]
|
||||
if not medal and division.battle.start:
|
||||
return division
|
||||
if not medal:
|
||||
ground_divs.append((0, division))
|
||||
else:
|
||||
ground_divs.append((division, medal.get('1').get('raw_value')))
|
||||
ground_divs.append((medal.get('1').get('raw_value'), division))
|
||||
|
||||
if self.config.air:
|
||||
return min(air_divs, key=lambda x: x[1])[0]
|
||||
elif self.config.ground:
|
||||
return min(ground_divs, key=lambda x: x[1])[0]
|
||||
else:
|
||||
return
|
||||
air_divs.sort(key=lambda z: (z[0], z[1].battle.start))
|
||||
ground_divs.sort(key=lambda z: (z[0], z[1].battle.start))
|
||||
return {'air': air_divs, 'ground': ground_divs}
|
||||
|
||||
@property
|
||||
def has_battle_contribution(self):
|
||||
@ -1611,7 +1609,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
self.travel_to_residence()
|
||||
break
|
||||
|
||||
def fight(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide = None, count: int = None) -> int:
|
||||
def fight(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide = None,
|
||||
count: int = None) -> int:
|
||||
"""Fight in a battle.
|
||||
|
||||
Will auto activate booster and travel if allowed to do it.
|
||||
@ -1657,7 +1656,7 @@ class CitizenMilitary(CitizenTravel):
|
||||
self.write_log("Hits: {:>4} | Damage: {}".format(total_hits, total_damage))
|
||||
ok_to_fight = False
|
||||
if total_damage:
|
||||
self.reporter.report_action("FIGHT", dict(battle=battle, side=side, dmg=total_damage,
|
||||
self.reporter.report_action("FIGHT", dict(battle=str(battle), side=str(side), dmg=total_damage,
|
||||
air=battle.has_air, hits=total_hits))
|
||||
return error_count
|
||||
|
||||
@ -1765,7 +1764,8 @@ class CitizenMilitary(CitizenTravel):
|
||||
if resp.json().get('error'):
|
||||
self.write_log(resp.json().get('message'))
|
||||
return False
|
||||
self._report_action("MILITARY_DIV_SWITCH", f"Switched to d{division.div} in battle {battle.id}", kwargs=resp.json())
|
||||
self._report_action("MILITARY_DIV_SWITCH", f"Switched to d{division.div} in battle {battle.id}",
|
||||
kwargs=resp.json())
|
||||
return True
|
||||
|
||||
def get_ground_hit_dmg_value(self, rang: int = None, strength: float = None, elite: bool = None, ne: bool = False,
|
||||
@ -1965,6 +1965,13 @@ class CitizenMilitary(CitizenTravel):
|
||||
return member.get('panelContents', {}).get('members', [{}])[0].get('dailyOrdersCompleted')
|
||||
return 0
|
||||
|
||||
def get_possibly_empty_medals(self):
|
||||
self.update_war_info()
|
||||
for battle in self.all_battles.values():
|
||||
for division in battle.div.values():
|
||||
if division.wall['dom'] == 50 or division.wall['dom'] > 98:
|
||||
yield division, division.wall['for'] == battle.invader.country.id
|
||||
|
||||
|
||||
class CitizenPolitics(BaseCitizen):
|
||||
def get_country_parties(self, country: constants.Country = None) -> dict:
|
||||
|
@ -1,6 +1,7 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import threading
|
||||
import weakref
|
||||
from decimal import Decimal
|
||||
from typing import Any, Dict, List, NamedTuple, Optional, Tuple, Union
|
||||
|
||||
@ -27,9 +28,10 @@ class Holding:
|
||||
id: int
|
||||
region: int
|
||||
companies: List["Company"]
|
||||
_citizen = weakref.ReferenceType
|
||||
|
||||
def __init__(self, _id: int, region: int, citizen):
|
||||
self.citizen = citizen
|
||||
self._citizen = weakref.ref(citizen)
|
||||
self.id: int = _id
|
||||
self.region: int = region
|
||||
self.companies: List["Company"] = list()
|
||||
@ -93,8 +95,13 @@ class Holding:
|
||||
def as_dict(self):
|
||||
return dict(name=str(self), id=self.id, region=self.region, companies=self.companies, wam_count=self.wam_count)
|
||||
|
||||
@property
|
||||
def citizen(self):
|
||||
return self._citizen()
|
||||
|
||||
|
||||
class Company:
|
||||
_holding: weakref.ReferenceType
|
||||
holding: Holding
|
||||
id: int
|
||||
quality: int
|
||||
@ -113,7 +120,7 @@ class Company:
|
||||
base_production: Decimal, wam_enabled: bool, can_wam: bool, cannot_wam_reason: str, industry: int,
|
||||
already_worked: bool, preset_works: int
|
||||
):
|
||||
self.holding: Holding = holding
|
||||
self._holding = weakref.ref(holding)
|
||||
self.id: int = _id
|
||||
self.industry: int = industry
|
||||
self.quality: int = self._get_real_quality(quality)
|
||||
@ -211,6 +218,10 @@ class Company:
|
||||
# noinspection PyProtectedMember
|
||||
return self.holding.citizen._post_economy_upgrade_company(self.id, level, self.holding.citizen.details.pin)
|
||||
|
||||
@property
|
||||
def holding(self):
|
||||
return self._holding()
|
||||
|
||||
|
||||
class MyCompanies:
|
||||
work_units: int = 0
|
||||
@ -218,13 +229,13 @@ class MyCompanies:
|
||||
ff_lockdown: int = 0
|
||||
|
||||
holdings: Dict[int, Holding]
|
||||
companies: List[Company]
|
||||
companies: weakref.WeakSet
|
||||
_citizen: weakref.ReferenceType
|
||||
|
||||
def __init__(self, citizen):
|
||||
from erepublik import Citizen
|
||||
self.citizen: Citizen = citizen
|
||||
self._citizen = weakref.ref(citizen)
|
||||
self.holdings: Dict[int, Holding] = dict()
|
||||
self.companies: List[Company] = list()
|
||||
self.companies: weakref.WeakSet = weakref.WeakSet()
|
||||
self.next_ot_time = utils.now()
|
||||
|
||||
def prepare_holdings(self, holdings: Dict[str, Dict[str, Any]]):
|
||||
@ -233,8 +244,9 @@ class MyCompanies:
|
||||
"""
|
||||
for holding in holdings.values():
|
||||
if holding.get('id') not in self.holdings:
|
||||
self.holdings.update(
|
||||
{int(holding.get('id')): Holding(holding['id'], holding['region_id'], self.citizen)})
|
||||
self.holdings.update({
|
||||
int(holding.get('id')): Holding(holding['id'], holding['region_id'], self.citizen)
|
||||
})
|
||||
if not self.holdings.get(0):
|
||||
self.holdings.update({0: Holding(0, 0, self.citizen)}) # unassigned
|
||||
|
||||
@ -258,7 +270,7 @@ class MyCompanies:
|
||||
company_dict.get('can_work_as_manager'), company_dict.get('cannot_work_as_manager_reason'),
|
||||
company_dict.get('industry_id'), company_dict.get('already_worked'), company_dict.get('preset_works')
|
||||
)
|
||||
self.companies.append(company)
|
||||
self.companies.add(company)
|
||||
holding.add_company(company)
|
||||
|
||||
def get_employable_factories(self) -> Dict[int, int]:
|
||||
@ -282,6 +294,8 @@ class MyCompanies:
|
||||
|
||||
def __clear_data(self):
|
||||
for holding in self.holdings.values():
|
||||
for company in holding.companies:
|
||||
del company
|
||||
holding.companies.clear()
|
||||
self.companies.clear()
|
||||
|
||||
@ -290,6 +304,10 @@ class MyCompanies:
|
||||
return dict(name=str(self), work_units=self.work_units, next_ot_time=self.next_ot_time,
|
||||
ff_lockdown=self.ff_lockdown, holdings=self.holdings, company_count=len(self.companies))
|
||||
|
||||
@property
|
||||
def citizen(self):
|
||||
return self._citizen()
|
||||
|
||||
|
||||
class Config:
|
||||
email = ""
|
||||
@ -528,7 +546,7 @@ class Reporter:
|
||||
queue=self.__to_update)
|
||||
|
||||
def __init__(self, citizen):
|
||||
self.citizen = citizen
|
||||
self._citizen = weakref.ref(citizen)
|
||||
self._req = Session()
|
||||
self.url = "https://api.erep.lv"
|
||||
self._req.headers.update({"user-agent": "Bot reporter v2"})
|
||||
@ -541,6 +559,10 @@ class Reporter:
|
||||
self.register_account()
|
||||
self.allowed = True
|
||||
|
||||
@property
|
||||
def citizen(self):
|
||||
return self._citizen()
|
||||
|
||||
def __update_key(self):
|
||||
self.key = hashlib.md5(bytes(f"{self.name}:{self.email}", encoding="UTF-8")).hexdigest()
|
||||
|
||||
@ -548,10 +570,10 @@ class Reporter:
|
||||
if self.__to_update:
|
||||
for unreported_data in self.__to_update:
|
||||
unreported_data.update(player_id=self.citizen_id, key=self.key)
|
||||
unreported_data = utils.json.load(utils.json.dumps(unreported_data, cls=MyJSONEncoder, sort_keys=True))
|
||||
unreported_data = utils.json.loads(utils.json.dumps(unreported_data, cls=MyJSONEncoder))
|
||||
self._req.post("{}/bot/update".format(self.url), json=unreported_data)
|
||||
self.__to_update.clear()
|
||||
data = utils.json.loads(utils.json.dumps(data, cls=MyJSONEncoder, sort_keys=True))
|
||||
data = utils.json.loads(utils.json.dumps(data, cls=MyJSONEncoder))
|
||||
r = self._req.post("{}/bot/update".format(self.url), json=data)
|
||||
return r
|
||||
|
||||
@ -645,12 +667,13 @@ class BattleSide:
|
||||
deployed: List[constants.Country]
|
||||
allies: List[constants.Country]
|
||||
battle: "Battle"
|
||||
_battle: weakref.ReferenceType
|
||||
country: constants.Country
|
||||
defender: bool
|
||||
|
||||
def __init__(self, battle: "Battle", country: constants.Country, points: int, allies: List[constants.Country],
|
||||
deployed: List[constants.Country], defender: bool):
|
||||
self.battle = battle
|
||||
self._battle = weakref.ref(battle)
|
||||
self.country = country
|
||||
self.points = points
|
||||
self.allies = allies
|
||||
@ -677,6 +700,10 @@ class BattleSide:
|
||||
return dict(points=self.points, country=self.country, defender=self.defender, allies=self.allies,
|
||||
deployed=self.deployed, battle=repr(self.battle))
|
||||
|
||||
@property
|
||||
def battle(self):
|
||||
return self._battle()
|
||||
|
||||
|
||||
class BattleDivision:
|
||||
id: int
|
||||
@ -689,6 +716,7 @@ class BattleDivision:
|
||||
terrain: int
|
||||
div: int
|
||||
battle: "Battle"
|
||||
_battle: weakref.ReferenceType
|
||||
|
||||
@property
|
||||
def as_dict(self):
|
||||
@ -715,7 +743,7 @@ class BattleDivision:
|
||||
:type wall_for: int
|
||||
:type wall_dom: float
|
||||
"""
|
||||
self.battle = battle
|
||||
self._battle = weakref.ref(battle)
|
||||
self.id = div_id
|
||||
self.end = end
|
||||
self.epic = epic
|
||||
@ -738,6 +766,10 @@ class BattleDivision:
|
||||
def __repr__(self):
|
||||
return f"<BattleDivision #{self.id} (battle #{self.battle.id})>"
|
||||
|
||||
@property
|
||||
def battle(self):
|
||||
return self._battle()
|
||||
|
||||
|
||||
class Battle:
|
||||
id: int
|
||||
|
@ -49,16 +49,16 @@ class Country:
|
||||
|
||||
|
||||
class Industries:
|
||||
__by_name = {'food': 1, 'weapons': 2, 'house': 4, 'aircraft': 23,
|
||||
'foodraw': 7, 'weaponraw': 12, 'weaponsraw': 12, 'houseraw': 18, 'aircraftraw': 24,
|
||||
__by_name = {'food': 1, 'weapon': 2, 'house': 4, 'aircraft': 23,
|
||||
'foodraw': 7, 'weaponraw': 12, 'houseraw': 18, 'aircraftraw': 24,
|
||||
'frm': 7, 'wrm': 12, 'hrm': 18, 'arm': 24,
|
||||
'frm q1': 7, 'frm q2': 8, 'frm q3': 9, 'frm q4': 10, 'frm q5': 11,
|
||||
'wrm q1': 12, 'wrm q2': 13, 'wrm q3': 14, 'wrm q4': 15, 'wrm q5': 16,
|
||||
'hrm q1': 18, 'hrm q2': 19, 'hrm q3': 20, 'hrm q4': 21, 'hrm q5': 22,
|
||||
'arm q1': 24, 'arm q2': 25, 'arm q3': 26, 'arm q4': 27, 'arm q5': 28}
|
||||
__by_id = {1: "Food", 2: "Weapons", 4: "House", 23: "Aircraft",
|
||||
__by_id = {1: "Food", 2: "Weapon", 4: "House", 23: "Aircraft",
|
||||
7: "foodRaw", 8: "FRM q2", 9: "FRM q3", 10: "FRM q4", 11: "FRM q5",
|
||||
12: "weaponsRaw", 13: "WRM q2", 14: "WRM q3", 15: "WRM q4", 16: "WRM q5",
|
||||
12: "weaponRaw", 13: "WRM q2", 14: "WRM q3", 15: "WRM q4", 16: "WRM q5",
|
||||
18: "houseRaw", 19: "HRM q2", 20: "HRM q3", 21: "HRM q4", 22: "HRM q5",
|
||||
24: "aircraftRaw", 25: "ARM q2", 26: "ARM q3", 27: "ARM q4", 28: "ARM q5"}
|
||||
|
||||
|
@ -230,7 +230,7 @@ def send_email(name: str, content: List[Any], player=None, local_vars: Dict[str,
|
||||
local_vars['citizen'] = repr(local_vars['citizen'])
|
||||
|
||||
from erepublik.classes import MyJSONEncoder
|
||||
files.append(('file', ("local_vars.json", json.dumps(local_vars, cls=MyJSONEncoder, sort_keys=True),
|
||||
files.append(('file', ("local_vars.json", json.dumps(local_vars, cls=MyJSONEncoder),
|
||||
"application/json")))
|
||||
if isinstance(player, Citizen):
|
||||
files.append(('file', ("instance.json", player.to_json(indent=True), "application/json")))
|
||||
@ -368,3 +368,11 @@ def get_air_hit_dmg_value(citizen_id: int, natural_enemy: bool = False, true_pat
|
||||
rang = r['military']['militaryData']['aircraft']['rankNumber']
|
||||
elite = r['citizenAttributes']['level'] > 100
|
||||
return calculate_hit(0, rang, true_patriot, elite, natural_enemy, booster, weapon_power)
|
||||
|
||||
|
||||
def _clear_up_battle_memory(battle):
|
||||
from . import classes
|
||||
battle: classes.Battle
|
||||
del battle.invader._battle, battle.defender._battle
|
||||
for div_id, division in battle.div.items():
|
||||
del division._battle
|
||||
|
@ -1,17 +1,18 @@
|
||||
bump2version==1.0.0
|
||||
coverage==5.2
|
||||
coverage==5.2.1
|
||||
edx-sphinx-theme==1.5.0
|
||||
flake8==3.8.3
|
||||
ipython==7.16.1
|
||||
isort==5.0.9
|
||||
pip==20.1.1
|
||||
PyInstaller==3.6
|
||||
ipython==7.17.0
|
||||
isort==5.4.2
|
||||
pip==20.2.2
|
||||
PyInstaller==4.0
|
||||
pytz==2020.1
|
||||
pytest==5.4.3
|
||||
responses==0.10.15
|
||||
setuptools==49.2.0
|
||||
Sphinx==3.1.2
|
||||
tox==3.16.1
|
||||
pytest==6.0.1
|
||||
responses==0.10.16
|
||||
setuptools==49.6.0
|
||||
Sphinx==3.2.1
|
||||
requests==2.24.0
|
||||
tox==3.19.0
|
||||
twine==3.2.0
|
||||
watchdog==0.10.3
|
||||
wheel==0.34.2
|
||||
wheel==0.35.1
|
||||
|
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 0.21.1
|
||||
current_version = 0.21.3
|
||||
commit = True
|
||||
tag = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\.?(?P<dev>\d+)?
|
||||
|
Reference in New Issue
Block a user