Lets deploy! Preperation for 8th of February

This commit is contained in:
Eriks K 2021-01-27 23:43:29 +02:00
parent 51a15874f2
commit 9acc2d2e65
4 changed files with 134 additions and 22 deletions

View File

@ -455,9 +455,39 @@ class ErepublikMilitaryAPI(CitizenBaseAPI):
data = dict(sideId=side_id, battleId=battle_id, _token=self.token, battleZoneId=zone_id) data = dict(sideId=side_id, battleId=battle_id, _token=self.token, battleZoneId=zone_id)
return self.post(f"{self.url}/military/fight-shooot/{battle_id}", data=data) return self.post(f"{self.url}/military/fight-shooot/{battle_id}", data=data)
def _post_fight_deploy_deploy_report_data(self, deployment_id: int): def _post_fight_deploy_deploy_report_data(self, deployment_id: int) -> Response:
data = dict(_token=self.token, deploymentId=deployment_id) data = dict(_token=self.token, deploymentId=deployment_id)
return self.post(f"{self.url}/military/fightDeploy-deployReportData", json=data) return self.post(f"{self.url}/military/fightDeploy-deployReportData", data=data)
def _post_fight_deploy_get_inventory(self, battle_id: int, side_id: int, battle_zone_id: int) -> Response:
data = dict(_token=self.token, battleId=battle_id, sideCountryId=side_id, battleZoneId=battle_zone_id)
return self.post(f"{self.url}/military/fightDeploy-getInventory", data=data)
def _post_fight_deploy_start_deploy(
self, battle_id: int, side_id: int, battle_zone_id: int, energy: int, weapon: int, **kwargs
) -> Response:
data = dict(_token=self.token, battleId=battle_id, battleZoneId=battle_zone_id, sideCountryId=side_id,
weaponQuality=weapon, totalEnergy=energy, **kwargs)
return self.post(f"{self.url}/military/fightDeploy-startDeploy", data=data)
def _get_main_session_captcha(self) -> Response:
return self.get(f'{self.url}/main/sessionCaptcha')
def _get_main_session_unlock_popup(self) -> Response:
return self.get(f'{self.url}/main/sessionUnlockPopup')
def _post_main_session_get_challenge(self, captcha_id: int) -> Response:
env = dict(l=['tets', ], s=[], c=["l_chathwe", "l_chatroom"], m=0)
data = dict(_token=self.token, captchaId=captcha_id, env=utils.b64json(env))
return self.post(f'{self.url}/main/sessionGetChallenge', data=data)
def _post_main_session_unlock(
self, captcha: int, image: str, challenge: str, coords: List[Dict[str, int]], src: str
) -> Response:
env = dict(l=['tets', ], s=[], c=["l_chathwe", "l_chatroom"], m=0)
data = dict(_token=self.token, captchaId=captcha, imageId=image, challengeId=challenge,
clickMatrix=utils.json.dumps(coords), isMobile=0, env=utils.b64json(env), src=src)
return self.post(f'{self.url}/main/sessionUnlock', data=data)
class ErepublikPoliticsAPI(CitizenBaseAPI): class ErepublikPoliticsAPI(CitizenBaseAPI):

View File

@ -27,6 +27,7 @@ class BaseCitizen(access_points.CitizenAPI):
eb_normal: int = 0 eb_normal: int = 0
eb_double: int = 0 eb_double: int = 0
eb_small: int = 0 eb_small: int = 0
eb_triple: int = 0
division: int = 0 division: int = 0
maverick: bool = False maverick: bool = False
@ -271,7 +272,7 @@ class BaseCitizen(access_points.CitizenAPI):
return return
self._last_inventory_update = self.now self._last_inventory_update = self.now
self.food.update(q1=0, q2=0, q3=0, q4=0, q5=0, q6=0, q7=0) self.food.update(q1=0, q2=0, q3=0, q4=0, q5=0, q6=0, q7=0)
self.eb_small = self.eb_double = self.eb_normal = 0 self.eb_triple = self.eb_small = self.eb_double = self.eb_normal = 0
active_items: types.InvFinal = {} active_items: types.InvFinal = {}
if data.get('activeEnhancements', {}).get('items', {}): if data.get('activeEnhancements', {}).get('items', {}):
for item_data in data.get('activeEnhancements', {}).get('items', {}).values(): for item_data in data.get('activeEnhancements', {}).get('items', {}).values():
@ -289,7 +290,8 @@ class BaseCitizen(access_points.CitizenAPI):
expiration_info = [_expire_value_to_python(v) for v in expire_info['value']] expiration_info = [_expire_value_to_python(v) for v in expire_info['value']]
if not item_data.get('icon') and item_data.get('isPackBooster'): if not item_data.get('icon') and item_data.get('isPackBooster'):
item_data['icon'] = f"//www.erepublik.com/images/icons/boosters/52px/{item_data.get('type')}.png" item_data['icon'] = f"//www.erepublik.com/images/icons/boosters/52px/{item_data.get('type')}.png"
icon = item_data['icon'] if item_data['icon'] else "//www.erepublik.net/images/modules/manager/tab_storage.png" icon = item_data['icon'] if item_data[
'icon'] else "//www.erepublik.net/images/modules/manager/tab_storage.png"
inv_item: types.InvFinalItem = dict( inv_item: types.InvFinalItem = dict(
name=item_data.get('name'), time_left=item_data['active']['time_left'], icon=icon, name=item_data.get('name'), time_left=item_data['active']['time_left'], icon=icon,
kind=kind, expiration=expiration_info, quality=item_data.get('quality', 0) kind=kind, expiration=expiration_info, quality=item_data.get('quality', 0)
@ -333,15 +335,12 @@ class BaseCitizen(access_points.CitizenAPI):
self.eb_normal = amount self.eb_normal = amount
elif q == 11: elif q == 11:
self.eb_double = amount self.eb_double = amount
elif q == 13: item_data.update(token='energy_bar')
self.eb_small += amount elif 11 < q < 17:
elif q == 14:
self.eb_small += amount
elif q == 15:
self.eb_small += amount self.eb_small += amount
item_data.update(token='energy_bar') item_data.update(token='energy_bar')
elif q == 16: elif q == 17:
self.eb_small += amount self.eb_triple = amount
item_data.update(token='energy_bar') item_data.update(token='energy_bar')
kind = re.sub(r'_q\d\d*', "", item_data.get('token')) kind = re.sub(r'_q\d\d*', "", item_data.get('token'))
@ -527,7 +526,7 @@ class BaseCitizen(access_points.CitizenAPI):
ret = super().as_dict ret = super().as_dict
ret.update( ret.update(
name=self.name, __str__=self.__str__(), name=self.name, __str__=self.__str__(),
ebs=dict(normal=self.eb_normal, double=self.eb_double, small=self.eb_small), ebs=dict(normal=self.eb_normal, double=self.eb_double, small=self.eb_small, triple=self.eb_triple),
promos=self.promos, inventory=self._inventory.as_dict, ot_points=self.ot_points, food=self.food, 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, division=self.division, maveric=self.maverick, eday=self.eday, wheel_of_fortune=self.wheel_of_fortune,
debug=self.debug, debug=self.debug,
@ -697,12 +696,10 @@ class BaseCitizen(access_points.CitizenAPI):
self.eb_normal -= amount self.eb_normal -= amount
elif q == '11': elif q == '11':
self.eb_double -= amount self.eb_double -= amount
elif q == '12': elif 11 < int(q) < 17:
self.eb_small -= amount
elif q == '15':
self.eb_small -= amount
elif q == '16':
self.eb_small -= amount self.eb_small -= amount
elif q == '17':
self.eb_triple -= amount
next_recovery = r_json.get('food_remaining_reset').split(":") next_recovery = r_json.get('food_remaining_reset').split(":")
self.energy.set_reference_time( self.energy.set_reference_time(
utils.good_timedelta(self.now, timedelta(seconds=int(next_recovery[1]) * 60 + int(next_recovery[2]))) utils.good_timedelta(self.now, timedelta(seconds=int(next_recovery[1]) * 60 + int(next_recovery[2])))
@ -2230,11 +2227,80 @@ class CitizenMilitary(CitizenTravel):
if division.wall['dom'] == 50 or division.wall['dom'] > 98: if division.wall['dom'] == 50 or division.wall['dom'] > 98:
yield division, division.wall['for'] == battle.invader.country.id yield division, division.wall['for'] == battle.invader.country.id
def report_fighting(self, battle: classes.Battle, invader: bool, division: classes.BattleDivision, damage: float, hits: int): def report_fighting(self, battle: classes.Battle, invader: bool, division: classes.BattleDivision, damage: float,
hits: int):
self.reporter.report_fighting(battle, invader, division, damage, hits) self.reporter.report_fighting(battle, invader, division, damage, hits)
if self.config.telegram: if self.config.telegram:
self.telegram.report_fight(battle, invader, division, damage, hits) self.telegram.report_fight(battle, invader, division, damage, hits)
def do_captcha_challenge(self) -> bool:
r = self._get_main_session_captcha()
data = re.search(r'\$j\.extend\(SERVER_DATA,([^)]+)\)', r.text)
if data:
data = utils.json_loads(utils.normalize_html_json(data.group(1)))
captcha_id = data.get('sessionValidation', {}).get("captchaId")
captcha_data = self._post_main_session_get_challenge(captcha_id).json()
coordinates = self.solve_captcha(captcha_data.get('src'))
r = self._post_main_session_unlock(
captcha_id, captcha_data['imageId'], captcha_data['challengeId'], coordinates, captcha_data['src']
).json()
if not r.get('error') and r.get('verified'):
return True
else:
self.report_error('Captcha failed!')
return self.do_captcha_challenge()
return False
def solve_captcha(self, src: str) -> List[Dict[str, int]]:
raise NotImplemented
def get_deploy_inventory(self, division: classes.BattleDivision, side: classes.BattleSide):
ret = self._post_fight_deploy_get_inventory(division.battle.id, side.id, division.id).json()
# if ret.get('recoverableEnergyBuyFood'):
# self.buy_food()
# return self.get_deploy_inventory(division, side)
if ret.get('captcha'):
while not self.do_captcha_challenge():
self.sleep(5)
return ret
def deploy(self, division: classes.BattleDivision, side: classes.BattleSide, energy: int):
_energy = int(energy)
deploy_inv = self.get_deploy_inventory(division, side)
if not deploy_inv['minEnergy'] <= energy <= deploy_inv['maxEnergy']:
return 0
energy_sources = {}
source_idx = 0
recoverable = deploy_inv['recoverableEnergy']
for source in reversed(sorted(deploy_inv['energySources'], key=lambda s: (s['type'], s.get('quality', 0)))):
if source['type'] == 'pool':
_energy -= source['energy']
elif source['type'] in ['food', 'energy_bar']:
recovers = source['energy'] / source['amount']
amount = recoverable // recovers
amount = amount if amount < source['amount'] else source['amount']
if amount > 0:
energy_sources.update({f'energySources[{source_idx}][quality]': source['quality']})
energy_sources.update({f'energySources[{source_idx}][amount]': amount})
source_idx += 1
used_energy = amount * recovers
recoverable -= used_energy
_energy -= used_energy
energy -= _energy
weapon_q = -1
weapon_strength = 0
if not division.is_air:
for weapon in sorted(deploy_inv['weapons'], key=lambda w: w['damageperHit']):
if weapon['damageperHit'] > weapon_strength and weapon['amount'] > 50:
weapon_q = weapon['quality']
r = self._post_fight_deploy_start_deploy(
division.battle.id, side.id, division.id, energy, weapon_q, **energy_sources
).json()
self.write_log(r.get('message'))
if r.get('error'):
self.report_error('Deploy failed!')
return energy
class CitizenPolitics(BaseCitizen): class CitizenPolitics(BaseCitizen):
def get_country_parties(self, country: constants.Country = None) -> dict: def get_country_parties(self, country: constants.Country = None) -> dict:

View File

@ -7,6 +7,7 @@ import time
import traceback import traceback
import unicodedata import unicodedata
import warnings import warnings
from base64 import b64encode
from decimal import Decimal from decimal import Decimal
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Union from typing import Any, Dict, List, Union
@ -429,3 +430,17 @@ def json_load(f, **kwargs):
def json_loads(s: str, **kwargs): def json_loads(s: str, **kwargs):
kwargs.update(object_hook=json_decode_object_hook) kwargs.update(object_hook=json_decode_object_hook)
return json.loads(s, **kwargs) return json.loads(s, **kwargs)
def b64json(obj: Union[Dict[str, Union[int, List[str]]], List[str]]):
if isinstance(obj, list):
return b64encode(json.dumps(obj).encode('utf-8')).decode('utf-8')
elif isinstance(obj, (int, str)):
return obj
elif isinstance(obj, dict):
for k, v in obj.items():
obj[k] = b64json(v)
else:
from .classes import ErepublikException
raise ErepublikException(f'Unhandled object type! obj is {type(obj)}')
return b64encode(json.dumps(obj).encode('utf-8')).decode('utf-8')

View File

@ -1,19 +1,20 @@
bump2version==1.0.1 bump2version==1.0.1
coverage==5.3.1 coverage==5.4
edx-sphinx-theme==1.6.1 edx-sphinx-theme==1.6.1
flake8==3.8.4 flake8==3.8.4
ipython>=7.19.0 ipython>=7.19.0
jedi!=0.18.0
isort==5.7.0 isort==5.7.0
pip==20.3.3 pip==21.0
pre-commit==2.9.3 pre-commit==2.9.3
pur==5.3.0 pur==5.3.0
PyInstaller==4.2 PyInstaller==4.2
PySocks==1.7.1 PySocks==1.7.1
pytest==6.2.1 pytest==6.2.2
pytz>=2020.5 pytz>=2020.5
requests>=2.25.1 requests>=2.25.1
responses==0.12.1 responses==0.12.1
setuptools==51.3.3 setuptools==52.0.0
Sphinx==3.4.3 Sphinx==3.4.3
twine==3.3.0 twine==3.3.0
wheel==0.36.2 wheel==0.36.2