3333
3434from .cache import Cache
3535from .clans import Clan , SearchClan
36- from .enums import ACHIEVEMENT_ORDER
3736from .errors import Forbidden , NotFound
3837from .miscmodels import Location , League
3938from .http import HTTPClient
@@ -1294,9 +1293,9 @@ def __init__(self, **options):
12941293 self ._cache_lookup ['cache_events' ] = cache_events
12951294
12961295 def _setup (self ):
1297- self ._clan_updates = None
1298- self ._player_updates = None
1299- self ._war_updates = None
1296+ self ._clan_updates = []
1297+ self ._player_updates = []
1298+ self ._war_updates = []
13001299
13011300 self ._active_state_tasks = {}
13021301
@@ -1426,7 +1425,7 @@ async def _run_event(self, event_name, coro, *args, **kwargs):
14261425 await coro (* args , ** kwargs )
14271426 except asyncio .CancelledError :
14281427 pass
1429- except Exception :
1428+ except ( Exception , BaseException ) :
14301429 try :
14311430 await self .on_event_error (event_name , * args , ** kwargs )
14321431 except asyncio .CancelledError :
@@ -1467,10 +1466,7 @@ async def add_clan_update(self, tags: Iterable, *, member_updates=False, retry_i
14671466 retry_interval : int
14681467 In seconds, how often the client 'checks' for updates. Defaults to 600 (10min)
14691468 """
1470- if not self ._clan_updates :
1471- self ._clan_updates = [n for n in tags ]
1472- else :
1473- self ._clan_updates .extend (n for n in tags )
1469+ self ._clan_updates .extend (n for n in tags )
14741470
14751471 if member_updates is True :
14761472 async for clan in self .get_clans (tags ):
@@ -1491,10 +1487,7 @@ def add_war_update(self, tags: Iterable, *, retry_interval=600):
14911487 retry_interval : int
14921488 In seconds, how often the client 'checks' for updates. Defaults to 600 (10min)
14931489 """
1494- if not self ._war_updates :
1495- self ._war_updates = [n for n in tags ]
1496- else :
1497- self ._war_updates .extend (n for n in tags )
1490+ self ._war_updates .extend (n for n in tags )
14981491
14991492 if retry_interval < 0 :
15001493 raise ValueError ('retry_interval must be greater than 0 seconds' )
@@ -1511,10 +1504,7 @@ def add_player_update(self, tags: Iterable, retry_interval=600):
15111504 retry_interval : int
15121505 In seconds, how often the client 'checks' for updates. Defaults to 600 (10min)
15131506 """
1514- if not self ._player_updates :
1515- self ._player_updates = [n for n in tags ]
1516- else :
1517- self ._player_updates .extend (n for n in tags )
1507+ self ._player_updates .extend (n for n in tags )
15181508
15191509 if retry_interval < 0 :
15201510 raise ValueError ('retry_interval must be greater than 0 seconds' )
@@ -1647,7 +1637,7 @@ async def _war_updater(self):
16471637 await self ._update_wars ()
16481638 self ._dispatch_batch_updates ('on_war' )
16491639 await asyncio .sleep (self ._war_retry_interval )
1650- except Exception :
1640+ except ( Exception , BaseException ) :
16511641 await self .on_event_error ('on_war_update' )
16521642 return await self ._war_updater ()
16531643
@@ -1658,7 +1648,7 @@ async def _clan_updater(self):
16581648 await self ._update_clans ()
16591649 self ._dispatch_batch_updates ('on_clan' )
16601650 await asyncio .sleep (self ._clan_retry_interval )
1661- except Exception :
1651+ except ( Exception , BaseException ) :
16621652 await self .on_event_error ('on_clan_update' )
16631653 return await self ._clan_updater ()
16641654
@@ -1669,66 +1659,25 @@ async def _player_updater(self):
16691659 await self ._update_players ()
16701660 self ._dispatch_batch_updates ('on_player' )
16711661 await asyncio .sleep (self ._player_retry_interval )
1672- except Exception :
1662+ except ( Exception , BaseException ) :
16731663 await self .on_event_error ('on_player_update' )
16741664 return await self ._player_updater ()
16751665
16761666 async def _check_member_count (self , cached_clan , new_clan ):
1677- differences = [n for n in new_clan ._members if n not in set (n .tag for n in cached_clan ._members )]
1667+ differences = [n for n in new_clan .members if n not in set (n .tag for n in cached_clan .members )]
16781668
16791669 for tag in differences :
1680- new_member = get (new_clan ._members , tag = tag )
1670+ new_member = get (new_clan .members , tag = tag )
16811671 if new_member :
16821672 self .dispatch ('on_clan_member_join' , new_member , new_clan )
16831673 continue
16841674
1685- member_left = get (cached_clan ._members , tag = tag )
1675+ member_left = get (cached_clan .members , tag = tag )
16861676 if member_left :
16871677 self .dispatch ('on_clan_member_leave' , member_left , new_clan )
1688- continue
16891678
16901679 return
16911680
1692- async def _update_clans (self ):
1693- if not self ._clan_updates :
1694- return
1695-
1696- async for clan in self .get_clans (self ._clan_updates , cache = False , update_cache = False ):
1697- cached_clan = cache_search_clans .get (clan .tag )
1698- if not cached_clan :
1699- cache_search_clans .add (clan .tag , clan )
1700- continue
1701-
1702- if clan == cached_clan :
1703- continue
1704-
1705- self .dispatch ('on_clan_update' , cached_clan , clan )
1706-
1707- if clan .member_count != cached_clan .member_count :
1708- await self ._check_member_count (cached_clan , clan )
1709-
1710- cached_clan ._data ['memberCount' ] = clan .member_count # hack for next line
1711-
1712- if clan ._data == cached_clan ._data :
1713- cache_search_clans .add (clan .tag , clan )
1714- continue
1715-
1716- if clan .members != cached_clan .members : # check for member donations and received
1717- for m , c in cached_clan ._members , clan ._members :
1718- if m .donations != c .donations :
1719- self .dispatch ('on_clan_member_donation' , m .donations , c .donations , m , clan )
1720- cached_clan ._data ['members' ][cached_clan .members .index (c )]['donations' ] = m .donations
1721- if m .received != c .received :
1722- self .dispatch ('on_clan_member_donation_received' , m .received , c .received , m , clan )
1723- cached_clan ._data ['members' ][cached_clan .members .index (c )]['donationsReceived' ] = m .received
1724-
1725- if clan ._data == cached_clan ._data :
1726- cache_search_clans .add (clan .tag , clan )
1727- continue
1728-
1729- self .dispatch ('on_clan_settings_update' , cached_clan , clan )
1730- cache_search_clans .add (clan .tag , clan )
1731-
17321681 async def _wait_for_state_change (self , state_to_wait_for , war ):
17331682 if state_to_wait_for == 'inWar' :
17341683 to_sleep = war .start_time .seconds_until
@@ -1784,12 +1733,12 @@ async def _update_wars(self):
17841733
17851734 async for war in self .get_current_wars (self ._war_updates , cache = False , update_cache = False ):
17861735 cached_war = cache_current_wars .get (war .clan_tag )
1736+
17871737 if not cached_war :
17881738 cache_current_wars .add (war .clan_tag , war )
17891739 continue
17901740
17911741 if war == cached_war :
1792- cache_current_wars .add (war .clan_tag , war )
17931742 continue
17941743
17951744 self .dispatch ('on_war_update' , cached_war , war )
@@ -1800,8 +1749,7 @@ async def _update_wars(self):
18001749 if not war ._attacks :
18011750 continue # if there are no attacks next line will raise TypeError.. we're not in war anymore anyway
18021751 if not cached_war ._attacks :
1803- new_attacks = [n for n in war ._attacks ] # war has just started
1804-
1752+ new_attacks = war .attacks
18051753 else :
18061754 new_attacks = [n for n in war ._attacks if n not in set (cached_war ._attacks )]
18071755
@@ -1826,79 +1774,146 @@ async def _update_players(self):
18261774
18271775 self .dispatch ('on_player_update' , cached_player , player )
18281776
1777+ # name
18291778 if player .name != cached_player .name :
18301779 self .dispatch ('on_player_name_change' , cached_player .name , player .name , player )
1831- cached_player ._data ['name' ] = player .name
18321780
1781+ # town/builder halls
18331782 if player .town_hall != cached_player .town_hall :
18341783 self .dispatch ('on_player_townhall_upgrade' , cached_player .town_hall , player .town_hall , player )
1835- cached_player ._data ['townHallLevel' ] = player .town_hall
1836-
18371784 if player .builder_hall != cached_player .builder_hall :
18381785 self .dispatch ('on_player_builderhall_upgrade' ,
18391786 cached_player .builder_hall , player .builder_hall , player )
1840- cached_player ._data ['builderHallLevel' ] = player .town_hall
18411787
1842- if player == cached_player :
1843- cache_search_players .add (player .tag , player )
1844- continue
1845-
1846- achievement_updates = (n for n in player ._achievements if n not in set (cached_player ._achievements ))
1788+ # best trophies/versus/war stars
1789+ if player .best_trophies != cached_player .best_trophies :
1790+ self .dispatch ('on_player_best_trophies_change' ,
1791+ cached_player .best_trophies , player .best_trophies , player )
1792+ if player .best_versus_trophies != cached_player .best_versus_trophies :
1793+ self .dispatch ('on_player_best_versus_trophies_change' ,
1794+ cached_player .best_versus_trophies , player .best_versus_trophies , player )
1795+ if player .war_stars != cached_player .war_stars :
1796+ self .dispatch ('on_player_war_stars_change' , cached_player .war_stars , player .war_stars , player )
1797+
1798+ # attacks win/defense/versus
1799+ if player .attack_wins != cached_player .attack_wins :
1800+ self .dispatch ('on_player_attack_wins_change' , cached_player .attack_wins , player .attack_wins , player )
1801+ if player .defense_wins != cached_player .defense_wins :
1802+ self .dispatch ('on_player_defense_wins_change' , cached_player .defense_wins , player .defense_wins , player )
1803+ if player .versus_attacks_wins != cached_player .versus_attacks_wins :
1804+ self .dispatch ('on_player_versus_attacks_change' ,
1805+ cached_player .versus_attacks_wins , player .versus_attacks_wins , player )
1806+
1807+ # trophies + league
1808+ if player .trophies != cached_player .trophies :
1809+ self .dispatch ('on_player_trophies_change' , cached_player .trophies , player .trophies , player )
1810+ if player .league != cached_player .league :
1811+ self .dispatch ('on_player_league_change' , cached_player .league , player .league , player )
1812+
1813+ # clan stuff: role, donations, received, rank and prev. rank
1814+ if player .role != cached_player .role :
1815+ self .dispatch ('on_player_role_change' , cached_player .role , player .role , player )
1816+ if player .donations != cached_player .donations :
1817+ self .dispatch ('on_player_donations_change' , cached_player .donations , player .donations , player )
1818+ if player .received != cached_player .received :
1819+ self .dispatch ('on_player_received_change' , cached_player .received , player .received , player )
1820+ if player .clan_rank != cached_player .clan_rank :
1821+ self .dispatch ('on_player_clan_rank_change' , cached_player .clan_rank , player .clan_rank , player )
1822+ if player .previous_clan_rank != cached_player .previous_clan_rank :
1823+ self .dispatch ('on_player_previous_clan_rank_change' ,
1824+ cached_player .clan_previous_rank , player .clan_previous_rank , player )
1825+
1826+ achievement_updates = (n for n in player .achievements if n not in set (cached_player .achievements ))
18471827 troop_upgrades = (n for n in player .troops if n not in set (cached_player .troops ))
18481828 spell_upgrades = (n for n in player .spells if n not in set (cached_player .spells ))
18491829 hero_upgrades = (n for n in player .heroes if n not in set (cached_player .heroes ))
18501830
18511831 for achievement in achievement_updates :
1852- old_achievement = get (cached_player ._achievements , name = achievement .name )
1832+ old_achievement = get (cached_player .achievements , name = achievement .name )
18531833 self .dispatch ('on_player_achievement_update' , old_achievement , achievement , player )
1854- i = ACHIEVEMENT_ORDER .index (achievement .name )
1855- cached_player ._data ['achievements' ][i ] = achievement ._data
18561834
18571835 for troop in troop_upgrades :
18581836 old_troop = get (cached_player .troops , name = troop .name )
18591837 self .dispatch ('on_player_troop_upgrade' , old_troop , troop , player )
1860- # this is a bit of a waste of resources, but we can't rely on order
1861- # as locked troops won't appear in the troops list from api,
1862- # meaning the order will change per-player.
1863- troops = [n ['name' ] for n in cached_player ._data ['troops' ]]
1864- try :
1865- i = troops .index (troop .name )
1866- except ValueError :
1867- self .dispatch ('on_player_troop_unlock' , troop , player )
1868- continue
1869- cached_player ._data ['troops' ][i ] = troop ._data
18701838
18711839 for spell in spell_upgrades :
18721840 old_spell = get (cached_player .spells , name = spell .name )
18731841 self .dispatch ('on_player_spell_upgrade' , old_spell , spell , player )
1874- # same issue as troops
1875- spells = [n ['name' ] for n in cached_player ._data ['spells' ]]
1876- try :
1877- i = spells .index (spell .name )
1878- except ValueError :
1879- self .dispatch ('on_player_spell_unlock' , spell , player )
1880- continue
1881-
1882- cached_player ._data ['spells' ][i ] = spell ._data
18831842
18841843 for hero in hero_upgrades :
18851844 old_hero = get (cached_player .heroes , name = hero .name )
18861845 self .dispatch ('on_player_hero_upgrade' , old_hero , hero , player )
1887- # same issue as troops
1888- heroes = [n ['name' ] for n in cached_player ._data ['heroes' ]]
1889- try :
1890- i = heroes .index (hero .name )
1891- except ValueError :
1892- self .dispatch ('on_player_hero_unlock' , hero , player )
1893- continue
18941846
1895- cached_player ._data ['heroes' ][i ] = hero ._data
1847+ async def _update_clans (self ):
1848+ if not self ._clan_updates :
1849+ return
1850+
1851+ async for clan in self .get_clans (self ._clan_updates , cache = False , update_cache = False ):
1852+ cached_clan = cache_search_clans .get (clan .tag )
1853+ if not cached_clan :
1854+ cache_search_clans .add (clan .tag , clan )
1855+ continue
18961856
1897- if cached_player == player :
1898- cache_search_players .add (player .tag , player )
1857+ if clan == cached_clan :
1858+ continue
1859+
1860+ self .dispatch ('on_clan_update' , cached_clan , clan )
1861+
1862+ if clan .member_count != cached_clan .member_count :
1863+ await self ._check_member_count (cached_clan , clan )
1864+ if clan .members != cached_clan .members :
1865+ await self ._update_clan_members (cached_clan , clan )
1866+
1867+ # settings
1868+ if clan .level != cached_clan .level :
1869+ self .dispatch ('on_clan_level_change' , cached_clan .level , clan .level , clan )
1870+ if clan .description != cached_clan .description :
1871+ self .dispatch ('on_clan_description_change' , cached_clan .description , clan .description , clan )
1872+ if clan .public_war_log != cached_clan .public_war_log :
1873+ self .dispatch ('on_clan_public_war_log_change' , cached_clan .public_war_log ,
1874+ clan .public_war_log , clan )
1875+ if clan .type != cached_clan .type :
1876+ self .dispatch ('on_clan_type_change' , cached_clan .type , clan .type , clan )
1877+ if clan .badge != cached_clan .badge :
1878+ self .dispatch ('on_clan_badge_change' , cached_clan .badge , clan .badge , clan )
1879+ if clan .required_trophies != cached_clan .required_trophies :
1880+ self .dispatch ('on_clan_required_trophies_change' ,
1881+ cached_clan .required_trophies , clan .required_trophies , clan )
1882+ if clan .war_frequency != cached_clan .war_frequency :
1883+ self .dispatch ('on_clan_war_frequency_change' , cached_clan .war_frequency , clan .war_frequency , clan )
1884+
1885+ # war win/loss/tie/streak
1886+ if clan .war_win_streak != cached_clan .war_win_streak :
1887+ self .dispatch ('on_clan_war_win_streak_change' , cached_clan .war_win_streak , clan .war_win_streak ,
1888+ clan )
1889+ if clan .war_wins != cached_clan .war_wins :
1890+ self .dispatch ('on_clan_war_win_change' , cached_clan .war_wins , clan .war_wins , clan )
1891+ if clan .war_ties != cached_clan .war_ties :
1892+ self .dispatch ('on_clan_war_tie_change' , cached_clan .war_ties , clan .war_ties , clan )
1893+ if clan .war_losses != cached_clan .war_losses :
1894+ self .dispatch ('on_clan_war_loss_change' , cached_clan .war_losses , clan .war_losses , clan )
1895+
1896+ cache_search_clans .add (clan .tag , clan )
1897+
1898+ async def _update_clan_members (self , cached_clan , clan ):
1899+ members = [n for n in clan .members if n != cached_clan .get_member (tag = n .tag )]
1900+ for m in members :
1901+ cached_member = cached_clan .get_member (tag = m .tag )
1902+ if not cached_member :
18991903 continue
19001904
1901- self .dispatch ('on_player_other_update' , cached_player , player )
1905+ if m .name != cached_member .name :
1906+ self .dispatch ('on_clan_member_name_change' , cached_member .name , m .name , m , clan )
1907+ if m .donations != cached_member .donations :
1908+ self .dispatch ('on_clan_member_donation' , cached_member .donations , m .donations , m , clan )
1909+ if m .received != cached_member .received :
1910+ self .dispatch ('on_clan_member_received' , cached_member .received , m .received , m , clan )
1911+ if m .role != cached_member .role :
1912+ self .dispatch ('on_clan_member_role_change' , cached_member .role , m .role , m , clan )
1913+ if m .clan_rank != cached_member .clan_rank :
1914+ self .dispatch ('on_clan_member_rank_change' , cached_member .clan_rank , m .clan_rank , m , clan )
1915+ if m .level != cached_member .level :
1916+ self .dispatch ('on_clan_member_level_change' , cached_member .level , m .level , m , clan )
19021917
19031918
19041919EventsClient .__doc__ = Client .__doc__
0 commit comments