|
|
|
@ -38,9 +38,9 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
energy: classes.Energy = None
|
|
|
|
|
details: classes.Details = None
|
|
|
|
|
politics: classes.Politics = None
|
|
|
|
|
my_companies: classes.MyCompanies = None
|
|
|
|
|
reporter: classes.Reporter = None
|
|
|
|
|
stop_threads: Event = None
|
|
|
|
|
concurrency_available: Event = None
|
|
|
|
|
telegram: classes.TelegramReporter = None
|
|
|
|
|
|
|
|
|
|
r: Response = None
|
|
|
|
@ -57,8 +57,6 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
self.my_companies = classes.MyCompanies(self)
|
|
|
|
|
self.reporter = classes.Reporter(self)
|
|
|
|
|
self.stop_threads = Event()
|
|
|
|
|
self.concurrency_available = Event()
|
|
|
|
|
self.concurrency_available.set()
|
|
|
|
|
self.telegram = classes.TelegramReporter(stop_event=self.stop_threads)
|
|
|
|
|
|
|
|
|
|
self.config.email = email
|
|
|
|
@ -341,6 +339,9 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
elif q == 15:
|
|
|
|
|
self.eb_small += amount
|
|
|
|
|
item_data.update(token='energy_bar')
|
|
|
|
|
elif q == 16:
|
|
|
|
|
self.eb_small += amount
|
|
|
|
|
item_data.update(token='energy_bar')
|
|
|
|
|
kind = re.sub(r'_q\d\d*', "", item_data.get('token'))
|
|
|
|
|
|
|
|
|
|
if item_data.get('token', "") == "house_q100":
|
|
|
|
@ -467,7 +468,7 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
self._req.debug = bool(debug)
|
|
|
|
|
|
|
|
|
|
def to_json(self, indent: bool = False) -> str:
|
|
|
|
|
return utils.json.dumps(self, cls=classes.MyJSONEncoder, indent=4 if indent else None)
|
|
|
|
|
return utils.json.dumps(self, cls=classes.MyJSONEncoder, indent=4 if indent else None, sort_keys=True)
|
|
|
|
|
|
|
|
|
|
def get_countries_with_regions(self) -> Set[constants.Country]:
|
|
|
|
|
r_json = self._post_main_travel_data().json()
|
|
|
|
@ -522,16 +523,24 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def as_dict(self):
|
|
|
|
|
ret = self.__dict__.copy()
|
|
|
|
|
ret.pop('stop_threads', None)
|
|
|
|
|
ret.pop('_CitizenMilitary__last_war_update_data', None)
|
|
|
|
|
ret.update(_properties=dict(
|
|
|
|
|
now=self.now, should_do_levelup=self.should_do_levelup, is_levelup_reachable=self.is_levelup_reachable,
|
|
|
|
|
max_time_till_full_ff=self.max_time_till_full_ff, is_levelup_close=self.is_levelup_close,
|
|
|
|
|
time_till_full_ff=self.time_till_full_ff, time_till_week_change=self.time_till_week_change,
|
|
|
|
|
next_wc_start=self.next_wc_start, next_reachable_energy=self.next_reachable_energy,
|
|
|
|
|
health_info=self.health_info))
|
|
|
|
|
|
|
|
|
|
ret = super().as_dict
|
|
|
|
|
ret.update(
|
|
|
|
|
name=self.name, __str__=self.__str__(),
|
|
|
|
|
ebs=dict(normal=self.eb_normal, double=self.eb_double, small=self.eb_small),
|
|
|
|
|
promos=self.promos, inventory=self._inventory.as_dict, ot_points=self.ot_points, food=self.food,
|
|
|
|
|
division=self.division, maveric=self.maverick, eday=self.eday, wheel_of_fortune=self.wheel_of_fortune,
|
|
|
|
|
debug=self.debug,
|
|
|
|
|
logged_in=self.logged_in, restricted_ip=self.restricted_ip, _properties=dict(
|
|
|
|
|
now=self.now, should_do_levelup=self.should_do_levelup, is_levelup_reachable=self.is_levelup_reachable,
|
|
|
|
|
max_time_till_full_ff=self.max_time_till_full_ff, is_levelup_close=self.is_levelup_close,
|
|
|
|
|
time_till_full_ff=self.time_till_full_ff, time_till_week_change=self.time_till_week_change,
|
|
|
|
|
next_wc_start=self.next_wc_start, next_reachable_energy=self.next_reachable_energy,
|
|
|
|
|
health_info=self.health_info),
|
|
|
|
|
_last_full_update=self._last_full_update, _last_inventory_update=self._last_inventory_update,
|
|
|
|
|
config=self.config.as_dict, energy=self.energy.as_dict, details=self.details.as_dict,
|
|
|
|
|
politics=self.politics.as_dict, my_companies=self.my_companies.as_dict, reporter=self.reporter.as_dict,
|
|
|
|
|
telegram=self.telegram.as_dict, stop_threads=self.stop_threads.is_set(), response=self.r,
|
|
|
|
|
)
|
|
|
|
|
return ret
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
@ -690,6 +699,10 @@ class BaseCitizen(access_points.CitizenAPI):
|
|
|
|
|
self.eb_double -= amount
|
|
|
|
|
elif q == "12":
|
|
|
|
|
self.eb_small -= amount
|
|
|
|
|
elif q == "15":
|
|
|
|
|
self.eb_small -= amount
|
|
|
|
|
elif q == "16":
|
|
|
|
|
self.eb_small -= amount
|
|
|
|
|
next_recovery = r_json.get("food_remaining_reset").split(":")
|
|
|
|
|
self.energy.set_reference_time(
|
|
|
|
|
utils.good_timedelta(self.now, timedelta(seconds=int(next_recovery[1]) * 60 + int(next_recovery[2])))
|
|
|
|
@ -973,7 +986,6 @@ class CitizenCompanies(BaseCitizen):
|
|
|
|
|
def work_as_manager_in_holding(self, holding: classes.Holding) -> Optional[Dict[str, Any]]:
|
|
|
|
|
return self._work_as_manager(holding)
|
|
|
|
|
|
|
|
|
|
@utils.wait_for_lock
|
|
|
|
|
def _work_as_manager(self, wam_holding: classes.Holding) -> Optional[Dict[str, Any]]:
|
|
|
|
|
if self.restricted_ip:
|
|
|
|
|
return None
|
|
|
|
@ -1043,7 +1055,7 @@ class CitizenCompanies(BaseCitizen):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CitizenEconomy(CitizenTravel):
|
|
|
|
|
def update_money(self, page: int = 0, currency: int = 62) -> Dict[str, Any]:
|
|
|
|
|
def update_money(self, page: int = 0, currency: int = 62):
|
|
|
|
|
"""
|
|
|
|
|
Gets monetary market offers to get exact amount of CC and Gold available
|
|
|
|
|
"""
|
|
|
|
@ -1053,7 +1065,6 @@ class CitizenEconomy(CitizenTravel):
|
|
|
|
|
resp_data = resp.json()
|
|
|
|
|
self.details.cc = float(resp_data.get("ecash").get("value"))
|
|
|
|
|
self.details.gold = float(resp_data.get("gold").get("value"))
|
|
|
|
|
return resp_data
|
|
|
|
|
|
|
|
|
|
def check_house_durability(self) -> Dict[int, datetime]:
|
|
|
|
|
ret = {}
|
|
|
|
@ -1075,7 +1086,7 @@ class CitizenEconomy(CitizenTravel):
|
|
|
|
|
local_cheapest = sorted(offers, key=lambda o: o.price)[0]
|
|
|
|
|
|
|
|
|
|
global_cheapest = self.get_market_offers("House", q)[f"q{q}"]
|
|
|
|
|
if global_cheapest.price + 200 < local_cheapest.price:
|
|
|
|
|
if global_cheapest.price + 2000 < local_cheapest.price:
|
|
|
|
|
if global_cheapest.price + 2000 < self.details.cc:
|
|
|
|
|
if self.travel_to_country(global_cheapest.country):
|
|
|
|
|
buy = self.buy_market_offer(global_cheapest, 1)
|
|
|
|
@ -1237,7 +1248,6 @@ class CitizenEconomy(CitizenTravel):
|
|
|
|
|
self._report_action("BOUGHT_PRODUCTS", json_ret.get('message'), kwargs=json_ret)
|
|
|
|
|
return json_ret
|
|
|
|
|
|
|
|
|
|
@utils.wait_for_lock
|
|
|
|
|
def buy_market_offer(self, offer: OfferItem, amount: int = None) -> Optional[Dict[str, Any]]:
|
|
|
|
|
if amount is None or amount > offer.amount:
|
|
|
|
|
amount = offer.amount
|
|
|
|
@ -1364,7 +1374,7 @@ class CitizenEconomy(CitizenTravel):
|
|
|
|
|
self.update_money()
|
|
|
|
|
cur = "g" if currency == 62 else "cc"
|
|
|
|
|
if success:
|
|
|
|
|
self._report_action("DONATE_MONEY", f"Successfully donated {amount}{cur} to citizen with id {citizen_id}!")
|
|
|
|
|
self.report_money_donation(citizen_id, amount, currency == 1)
|
|
|
|
|
else:
|
|
|
|
|
self._report_action("DONATE_MONEY", f"Unable to donate {amount}{cur}!")
|
|
|
|
|
return success
|
|
|
|
@ -1448,6 +1458,16 @@ class CitizenEconomy(CitizenTravel):
|
|
|
|
|
f" treasury", kwargs=r.json())
|
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
def report_money_donation(self, citizen_id: int, amount: float, is_currency: bool = True):
|
|
|
|
|
self.reporter.report_money_donation(citizen_id, amount, is_currency)
|
|
|
|
|
if self.config.telegram:
|
|
|
|
|
self.telegram.report_money_donation(citizen_id, amount, is_currency)
|
|
|
|
|
|
|
|
|
|
def report_item_donation(self, citizen_id: int, amount: float, quality: int, industry: str):
|
|
|
|
|
self.reporter.report_item_donation(citizen_id, amount, quality, industry)
|
|
|
|
|
if self.config.telegram:
|
|
|
|
|
self.telegram.report_item_donation(citizen_id, amount, f"{industry} q{quality}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CitizenLeaderBoard(BaseCitizen):
|
|
|
|
|
def get_aircraft_damage_rankings(self, country: int, weeks: int = 0, mu: int = 0) -> Dict[str, any]:
|
|
|
|
@ -1528,11 +1548,15 @@ class CitizenMedia(BaseCitizen):
|
|
|
|
|
|
|
|
|
|
class CitizenMilitary(CitizenTravel):
|
|
|
|
|
all_battles: Dict[int, classes.Battle] = None
|
|
|
|
|
countries: Dict[int, Dict[str, Union[str, List[int]]]] = None
|
|
|
|
|
__last_war_update_data = None
|
|
|
|
|
|
|
|
|
|
active_fs: bool = False
|
|
|
|
|
boosters: Dict[int, Dict[int, int]] = {100: {}, 50: {}}
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def as_dict(self):
|
|
|
|
|
d = super().as_dict
|
|
|
|
|
d.update(active_fs=self.active_fs, all_battles=self.all_battles)
|
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
def update_war_info(self):
|
|
|
|
|
if self.__last_war_update_data and self.__last_war_update_data.get('last_updated',
|
|
|
|
@ -1543,17 +1567,6 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
if r_json.get("countries"):
|
|
|
|
|
if self.all_battles is None:
|
|
|
|
|
self.all_battles = {}
|
|
|
|
|
if self.countries is None:
|
|
|
|
|
self.countries = {}
|
|
|
|
|
countries = {}
|
|
|
|
|
for c_id, c_data in r_json.get("countries").items():
|
|
|
|
|
if int(c_id) not in countries:
|
|
|
|
|
countries.update({
|
|
|
|
|
int(c_id): {"name": c_data.get("name"), "allies": c_data.get("allies")}
|
|
|
|
|
})
|
|
|
|
|
else:
|
|
|
|
|
countries[int(c_id)].update(allies=c_data.get("allies"))
|
|
|
|
|
self.countries = countries
|
|
|
|
|
self.__last_war_update_data = r_json
|
|
|
|
|
if r_json.get("battles"):
|
|
|
|
|
all_battles = {}
|
|
|
|
@ -1805,21 +1818,22 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
self.travel_to_residence()
|
|
|
|
|
break
|
|
|
|
|
|
|
|
|
|
@utils.wait_for_lock
|
|
|
|
|
def fight(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide = None,
|
|
|
|
|
count: int = None) -> Optional[int]:
|
|
|
|
|
count: int = None, use_ebs: bool = False) -> Optional[int]:
|
|
|
|
|
"""Fight in a battle.
|
|
|
|
|
|
|
|
|
|
Will auto activate booster and travel if allowed to do it.
|
|
|
|
|
:param battle: Battle battle to fight in
|
|
|
|
|
:type battle: Battle
|
|
|
|
|
:param division: Division number to fight in available choices
|
|
|
|
|
:type division: BattleDivision
|
|
|
|
|
:param side: BattleSide or None. Battle side to fight in, If side not == invader id or not in invader deployed
|
|
|
|
|
allies list, then defender's side is chosen
|
|
|
|
|
:type side: BattleSide
|
|
|
|
|
:param count: How many hits to do, if not specified self.should_fight() is called.
|
|
|
|
|
:type count: int
|
|
|
|
|
:param division: Division number to fight in available choices
|
|
|
|
|
:type division: BattleDivision
|
|
|
|
|
:param use_ebs: Should use energy bars if count > 0 and not enough food_fights
|
|
|
|
|
:type use_ebs: bool
|
|
|
|
|
:return: None if no errors while fighting, otherwise error count.
|
|
|
|
|
:rtype: int
|
|
|
|
|
"""
|
|
|
|
@ -1849,15 +1863,13 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
error_count += error
|
|
|
|
|
else:
|
|
|
|
|
self._eat('blue')
|
|
|
|
|
if count > 0 and self.energy.recovered < 50 and use_ebs:
|
|
|
|
|
self._eat('orange')
|
|
|
|
|
if self.energy.recovered < 50 or error_count >= 10 or count <= 0:
|
|
|
|
|
self.write_log(f"Hits: {total_hits:>4} | Damage: {total_damage}")
|
|
|
|
|
ok_to_fight = False
|
|
|
|
|
if total_damage:
|
|
|
|
|
self.report_fighting(battle, not side.is_defender, division, total_damage, total_hits)
|
|
|
|
|
# self.reporter.report_action('FIGHT', dict(battle_id=battle.id, side=side, dmg=total_damage,
|
|
|
|
|
# air=battle.has_air, hits=total_hits,
|
|
|
|
|
# round=battle.zone_id,
|
|
|
|
|
# extra=dict(battle=battle, side=side)))
|
|
|
|
|
return error_count
|
|
|
|
|
|
|
|
|
|
def _shoot(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide):
|
|
|
|
@ -1922,7 +1934,6 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
|
|
|
|
|
return hits, err, damage
|
|
|
|
|
|
|
|
|
|
@utils.wait_for_lock
|
|
|
|
|
def deploy_bomb(self, battle: classes.Battle, division: classes.BattleDivision, bomb_id: int, inv_side: bool,
|
|
|
|
|
count: int = 1) -> Optional[int]:
|
|
|
|
|
"""Deploy bombs in a battle for given side.
|
|
|
|
@ -2020,7 +2031,7 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
return utils.calculate_hit(0, rang, True, elite, ne, 0, 20 if weapon else 0)
|
|
|
|
|
|
|
|
|
|
def activate_damage_booster(self, ground: bool = True) -> int:
|
|
|
|
|
kind = 'damageBoosters' if ground else 'aircraftDamageBoosters'
|
|
|
|
|
kind = 'damage' if ground else 'aircraftDamage'
|
|
|
|
|
if self.config.boosters and not self.get_active_damage_booster(ground):
|
|
|
|
|
booster: Optional[types.InvFinalItem] = None
|
|
|
|
|
for quality, data in sorted(self.inventory.boosters.get(kind, {}).items(), key=lambda x: x[0]):
|
|
|
|
@ -2038,7 +2049,7 @@ class CitizenMilitary(CitizenTravel):
|
|
|
|
|
return self.get_active_damage_booster(ground)
|
|
|
|
|
|
|
|
|
|
def get_active_damage_booster(self, ground: bool = True) -> int:
|
|
|
|
|
kind = 'damageBoosters' if ground else 'aircraftDamageBoosters'
|
|
|
|
|
kind = 'damage' if ground else 'aircraftDamage'
|
|
|
|
|
boosters = self.inventory.active.get(kind, {})
|
|
|
|
|
quality = 0
|
|
|
|
|
for q, boost in boosters.items():
|
|
|
|
@ -2380,6 +2391,12 @@ class CitizenTasks(CitizenEconomy):
|
|
|
|
|
ot_points: int = 0
|
|
|
|
|
next_ot_time: datetime = None
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def as_dict(self):
|
|
|
|
|
d = super().as_dict
|
|
|
|
|
d.update(tg_contract=self.tg_contract, ot_points=self.ot_points, next_ot_time=self.next_ot_time)
|
|
|
|
|
return d
|
|
|
|
|
|
|
|
|
|
def eat(self):
|
|
|
|
|
""" Eat food """
|
|
|
|
|
self._eat("blue")
|
|
|
|
@ -2507,8 +2524,8 @@ class CitizenTasks(CitizenEconomy):
|
|
|
|
|
self.ot_points = ot.get("points", 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Citizen(CitizenAnniversary, CitizenCompanies, CitizenLeaderBoard,
|
|
|
|
|
CitizenMedia, CitizenPolitics, CitizenSocial, CitizenMilitary, CitizenTasks):
|
|
|
|
|
class _Citizen(CitizenAnniversary, CitizenCompanies, CitizenLeaderBoard,
|
|
|
|
|
CitizenMedia, CitizenPolitics, CitizenSocial, CitizenMilitary, CitizenTasks):
|
|
|
|
|
def __init__(self, email: str = "", password: str = "", auto_login: bool = False):
|
|
|
|
|
super().__init__(email, password)
|
|
|
|
|
self._last_full_update = constants.min_datetime
|
|
|
|
@ -2519,10 +2536,18 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenLeaderBoard,
|
|
|
|
|
@classmethod
|
|
|
|
|
def load_from_dump(cls, dump_name: str = ""):
|
|
|
|
|
filename = dump_name if dump_name else f"{cls.__name__}__dump.json"
|
|
|
|
|
player: Citizen = super().load_from_dump(filename) # noqa
|
|
|
|
|
player: _Citizen = super().load_from_dump(filename) # noqa
|
|
|
|
|
player.login()
|
|
|
|
|
return player
|
|
|
|
|
|
|
|
|
|
def _eat(self, colour: str = "blue") -> Response:
|
|
|
|
|
resp = super()._eat(colour)
|
|
|
|
|
if not any([resp.json().get("units_consumed").values()]):
|
|
|
|
|
if colour == 'orange' and resp.json().get('food_remaining'):
|
|
|
|
|
self.eat()
|
|
|
|
|
return self._eat(colour)
|
|
|
|
|
return resp
|
|
|
|
|
|
|
|
|
|
def config_setup(self, **kwargs):
|
|
|
|
|
self.config.reset()
|
|
|
|
|
for key, value in kwargs.items():
|
|
|
|
@ -2880,3 +2905,156 @@ class Citizen(CitizenAnniversary, CitizenCompanies, CitizenLeaderBoard,
|
|
|
|
|
self.stop_threads.wait(90)
|
|
|
|
|
except: # noqa
|
|
|
|
|
self.report_error('Command central is broken')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Citizen(_Citizen):
|
|
|
|
|
_concurrency_lock: Event
|
|
|
|
|
_update_lock: Event
|
|
|
|
|
_update_timeout: int = 10
|
|
|
|
|
_concurrency_timeout: int = 600
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
self._concurrency_lock = Event()
|
|
|
|
|
self._concurrency_lock.set()
|
|
|
|
|
self._update_lock = Event()
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
super().__init__(*args, **kwargs)
|
|
|
|
|
|
|
|
|
|
def update_weekly_challenge(self):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_weekly_challenge()
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def update_companies(self):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_companies()
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def update_war_info(self):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_war_info()
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def update_job_info(self):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_job_info()
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def update_money(self, page: int = 0, currency: int = 62):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_money(page, currency)
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def update_inventory(self):
|
|
|
|
|
if not self._update_lock.wait(self._update_timeout):
|
|
|
|
|
e = f'Update concurrency not freed in {self._update_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._update_lock.clear()
|
|
|
|
|
super().update_inventory()
|
|
|
|
|
finally:
|
|
|
|
|
self._update_lock.set()
|
|
|
|
|
|
|
|
|
|
def _work_as_manager(self, wam_holding: classes.Holding) -> Optional[Dict[str, Any]]:
|
|
|
|
|
if not self._concurrency_lock.wait(self._concurrency_timeout):
|
|
|
|
|
e = f'Concurrency not freed in {self._concurrency_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._concurrency_lock.clear()
|
|
|
|
|
return super()._work_as_manager(wam_holding)
|
|
|
|
|
finally:
|
|
|
|
|
self._concurrency_lock.set()
|
|
|
|
|
|
|
|
|
|
def fight(self, battle: classes.Battle, division: classes.BattleDivision, side: classes.BattleSide = None,
|
|
|
|
|
count: int = None, use_ebs: bool = False) -> Optional[int]:
|
|
|
|
|
if not self._concurrency_lock.wait(self._concurrency_timeout):
|
|
|
|
|
e = f'Concurrency not freed in {self._concurrency_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._concurrency_lock.clear()
|
|
|
|
|
return super().fight(battle, division, side, count, use_ebs)
|
|
|
|
|
finally:
|
|
|
|
|
self._concurrency_lock.set()
|
|
|
|
|
|
|
|
|
|
def deploy_bomb(self, battle: classes.Battle, division: classes.BattleDivision, bomb_id: int, inv_side: bool,
|
|
|
|
|
count: int = 1) -> Optional[int]:
|
|
|
|
|
if not self._concurrency_lock.wait(self._concurrency_timeout):
|
|
|
|
|
e = f'Concurrency not freed in {self._concurrency_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._concurrency_lock.clear()
|
|
|
|
|
return super().deploy_bomb(battle, division, bomb_id, inv_side, count)
|
|
|
|
|
finally:
|
|
|
|
|
self._concurrency_lock.set()
|
|
|
|
|
|
|
|
|
|
def buy_market_offer(self, offer: OfferItem, amount: int = None) -> Optional[Dict[str, Any]]:
|
|
|
|
|
if not self._concurrency_lock.wait(self._concurrency_timeout):
|
|
|
|
|
e = f'Concurrency not freed in {self._concurrency_timeout}sec!'
|
|
|
|
|
self.write_log(e)
|
|
|
|
|
if self.debug:
|
|
|
|
|
self.report_error(e)
|
|
|
|
|
return None
|
|
|
|
|
try:
|
|
|
|
|
self._concurrency_lock.clear()
|
|
|
|
|
return super().buy_market_offer(offer, amount)
|
|
|
|
|
finally:
|
|
|
|
|
self._concurrency_lock.set()
|
|
|
|
|
|
|
|
|
|
@property
|
|
|
|
|
def as_dict(self):
|
|
|
|
|
d = super().as_dict
|
|
|
|
|
d.update(locks=dict(concurrency_lock=self._concurrency_lock.is_set(), update_lock=self._update_lock.is_set(),
|
|
|
|
|
concurrency_timeout=self._concurrency_timeout, update_timeout=self._update_timeout))
|
|
|
|
|
return d
|
|
|
|
|