diff --git a/royalpack/commands/brawlhalla.py b/royalpack/commands/brawlhalla.py deleted file mode 100644 index a4d2939b..00000000 --- a/royalpack/commands/brawlhalla.py +++ /dev/null @@ -1,169 +0,0 @@ -from typing import * - -import asyncio -import logging -import aiohttp - -from royalnet.backpack import tables as rbt -import royalnet.commands as rc -import royalnet.utils as ru -from sqlalchemy import or_, and_ - -from .abstract.linker import LinkerCommand -from ..tables import Steam, Brawlhalla, BrawlhallaDuo -from ..types import BrawlhallaRank, BrawlhallaMetal, BrawlhallaTier, Updatable - -log = logging.getLogger(__name__) - - -class BrawlhallaCommand(LinkerCommand): - name: str = "brawlhalla" - - aliases = ["bh", "bruhalla", "bruhlalla"] - - description: str = "Visualizza le tue statistiche di Brawlhalla." - - syntax: str = "" - - def token(self): - return self.config['brawlhalla']['token'] - - async def get_updatables_of_user(self, session, user: rbt.User) -> List[Brawlhalla]: - return user.steam - - async def get_updatables(self, session) -> List[Brawlhalla]: - return await ru.asyncify(session.query(self.alchemy.get(Steam)).all) - - async def create(self, - session, - user: rbt.User, - args: rc.CommandArgs, - data: Optional[rc.CommandData] = None) -> Optional[Brawlhalla]: - raise rc.InvalidInputError("Brawlhalla accounts are automatically linked from Steam.") - - async def update(self, session, obj, change: Callable[[str, Any], Awaitable[None]]): - BrawlhallaT = self.alchemy.get(Brawlhalla) - DuoT = self.alchemy.get(BrawlhallaDuo) - log.info(f"Updating: {obj}") - async with aiohttp.ClientSession() as hcs: - bh: Brawlhalla = obj.brawlhalla - if bh is None: - log.debug(f"Checking if player has an account...") - async with hcs.get(f"https://api.brawlhalla.com/search?steamid={obj.steamid.as_64}&api_key={self.token()}") as response: - if response.status != 200: - raise rc.ExternalError(f"Brawlhalla API /search returned {response.status}!") - j = await response.json() - if j == {} or j == []: - log.debug("No account found.") - return - bh = BrawlhallaT( - steam=obj, - brawlhalla_id=j["brawlhalla_id"], - name=j["name"] - ) - session.add(bh) - session.flush() - - async with hcs.get(f"https://api.brawlhalla.com/player/{bh.brawlhalla_id}/ranked?api_key={self.token()}") as response: - if response.status != 200: - raise rc.ExternalError(f"Brawlhalla API /ranked returned {response.status}!") - j = await response.json() - if j == {} or j == []: - log.debug("No ranked info found.") - else: - await self._change(session=session, obj=bh, attribute="rating_1v1", new=j["rating"]) - metal_name, tier_name = j["tier"].split(" ", 1) - metal = BrawlhallaMetal[metal_name.upper()] - tier = BrawlhallaTier(int(tier_name)) - rank = BrawlhallaRank(metal=metal, tier=tier) - await self._change(session=session, obj=bh, attribute="rank_1v1", new=rank) - - for jduo in j.get("2v2", []): - bhduo: Optional[BrawlhallaDuo] = await ru.asyncify( - session.query(DuoT) - .filter( - or_( - and_( - DuoT.id_one == jduo["brawlhalla_id_one"], - DuoT.id_two == jduo["brawlhalla_id_two"] - ), - and_( - DuoT.id_one == jduo["brawlhalla_id_two"], - DuoT.id_two == jduo["brawlhalla_id_one"] - ) - ) - ) - .one_or_none - ) - if bhduo is None: - if bh.brawlhalla_id == jduo["brawlhalla_id_one"]: - otherbh: Optional[Brawlhalla] = await ru.asyncify( - session.query(BrawlhallaT).get, jduo["brawlhalla_id_two"] - ) - else: - otherbh: Optional[Brawlhalla] = await ru.asyncify( - session.query(BrawlhallaT).get, jduo["brawlhalla_id_one"] - ) - if otherbh is None: - continue - bhduo = DuoT( - one=bh, - two=otherbh, - ) - - session.add(bhduo) - await self._change(session=session, obj=bhduo, attribute="rating_2v2", new=jduo["rating"]) - metal_name, tier_name = jduo["tier"].split(" ", 1) - metal = BrawlhallaMetal[metal_name.upper()] - tier = BrawlhallaTier(int(tier_name)) - rank = BrawlhallaRank(metal=metal, tier=tier) - await self._change(session=session, obj=bhduo, attribute="rank_2v2", new=rank) - - async def on_increase(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None: - if attribute == "rank_1v1": - await self.notify(f"📈 [b]{obj.steam.user}[/b] è salito a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla! Congratulazioni!") - elif attribute == "rank_2v2": - await self.notify(f"📈 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono saliti a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla! Congratulazioni!") - - async def on_unchanged(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None: - pass - - async def on_decrease(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: Any) -> None: - if attribute == "rank_1v1": - await self.notify(f"📉 [b]{obj.steam.user}[/b] è sceso a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla.") - elif attribute == "rank_2v2": - await self.notify(f"📉 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] sono scesi a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla.") - - async def on_first(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: None, new: Any) -> None: - if attribute == "rank_1v1": - await self.notify(f"🌟 [b]{obj.steam.user}[/b] si è classificato a [b]{new}[/b] ({obj.rating_1v1} MMR) in 1v1 su Brawlhalla!") - elif attribute == "rank_2v2": - await self.notify(f"🌟 [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] si sono classificati a [b]{new}[/b] ({obj.rating_2v2} MMR) in 2v2 su Brawlhalla!") - - async def on_reset(self, session, obj: Union[Brawlhalla, BrawlhallaDuo], attribute: str, old: Any, new: None) -> None: - if attribute == "rank_1v1": - await self.notify(f"⬜️ [b]{obj.steam.user}[/b] non ha più un rank su Brawlhalla.") - elif attribute == "rank_2v2": - await self.notify(f"⬜️ [b]{obj.one.steam.user}[/b] e [b]{obj.two.steam.user}[/b] non hanno più un rank su Brawlhalla.") - - def describe(self, obj: Steam) -> str: - bh = obj.brawlhalla - - string = [f"ℹ️ [b]{bh.name}[/b]", ""] - - if bh.rank_1v1: - string.append("👤 [b]1v1[/b]") - string.append(f"[b]{bh.rank_1v1}[/b] ({bh.rating_1v1} MMR)") - string.append("") - - if len(bh.duos) != 0: - string.append(f"👥 [b]2v2[/b]") - - for duo in sorted(bh.duos, key=lambda d: -d.rating_2v2): - other = duo.other(bh) - string.append(f"Con [b]{other.steam.user}[/b]: [b]{duo.rank_2v2}[/b] ({duo.rating_2v2} MMR)") - - if len(bh.duos) != 0: - string.append("") - - return "\n".join(string) diff --git a/royalpack/commands/spell.py b/royalpack/commands/spell.py index e815bfd2..d6c20489 100644 --- a/royalpack/commands/spell.py +++ b/royalpack/commands/spell.py @@ -2,6 +2,7 @@ from typing import * import royalnet.commands as rc import royalnet.utils as ru import royalspells as rs +import datetime class SpellCommand(rc.Command): @@ -27,6 +28,14 @@ class SpellCommand(rc.Command): rows.append(f"Multiattacco: [b]×{dmg.repeat}[/b]") rows.append("") + # Halloween 2020 + possible_dmg = (dmg.dice_number * dmg.dice_type + dmg.constant) * dmg.repeat + if possible_dmg >= 250: + async with data.session_acm() as session: + author = await data.find_author(session=session, required=False) + if author is not None and author.halloween2020 is not None: + author.halloween2020.i = datetime.datetime.now() + if spell.healing_component: heal: rs.HealingComponent = spell.healing_component constant_str: str = f"{heal.constant:+d}" if heal.constant != 0 else "" diff --git a/royalpack/commands/trionfireali.py b/royalpack/commands/trionfireali.py new file mode 100644 index 00000000..384861ab --- /dev/null +++ b/royalpack/commands/trionfireali.py @@ -0,0 +1,54 @@ +from typing import * +import logging +import aiohttp +import royalnet.commands as rc +import royalnet.utils as ru +from royalnet.backpack import tables as rbt +from .abstract.linker import LinkerCommand + +from ..tables import Steam, Dota +from ..types import DotaRank + +log = logging.getLogger(__name__) + + +class TrionfirealiCommand(LinkerCommand): + name: str = "trionfireali" + + description: str = "Visualizza il tuo pr⊕gress⊕ nei Tri⊕nfi Reali!" + + syntax: str = "" + + def describe(self, obj: Steam) -> str: + raise NotImplementedError() + + async def get_updatables_of_user(self, session, user: rbt.User) -> List[Dota]: + raise NotImplementedError() + + async def get_updatables(self, session) -> List[Dota]: + raise NotImplementedError() + + async def create(self, + session, + user: rbt.User, + args: rc.CommandArgs, + data: Optional[rc.CommandData] = None) -> Optional[Dota]: + raise rc.InvalidInputError("Trionfi Reali accounts are automatically linked from Steam.") + + async def update(self, session, obj: Steam, change: Callable[[str, Any], Awaitable[None]]): + raise NotImplementedError() + + async def on_increase(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None: + pass + + async def on_unchanged(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None: + pass + + async def on_decrease(self, session, obj: Dota, attribute: str, old: Any, new: Any) -> None: + pass + + async def on_first(self, session, obj: Dota, attribute: str, old: None, new: Any) -> None: + pass + + async def on_reset(self, session, obj: Dota, attribute: str, old: Any, new: None) -> None: + pass diff --git a/royalpack/stars/api_user_ryg.py b/royalpack/stars/api_user_ryg.py index 893743f2..7f61ed09 100644 --- a/royalpack/stars/api_user_ryg.py +++ b/royalpack/stars/api_user_ryg.py @@ -42,6 +42,5 @@ class ApiUserRygStar(rca.ApiStar): "leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends], "osu": [osu.json() for osu in user.osu], "trivia": user.trivia_score.json() if user.trivia_score is not None else None, - "halloween2020": user.halloween2020.json() if user.halloween2020 is not None else None, } return result diff --git a/royalpack/stars/api_user_ryg_list.py b/royalpack/stars/api_user_ryg_list.py index 74eaaaa4..09048ea2 100644 --- a/royalpack/stars/api_user_ryg_list.py +++ b/royalpack/stars/api_user_ryg_list.py @@ -23,5 +23,4 @@ class ApiUserRygListStar(rca.ApiStar): "leagueoflegends": [leagueoflegends.json() for leagueoflegends in user.leagueoflegends], "osu": [osu.json() for osu in user.osu], "trivia": user.trivia_score.json() if user.trivia_score is not None else None, - "halloween2020": user.halloween2020.json() if user.halloween2020 is not None else None, } for user in users if "member" in user.roles] diff --git a/royalpack/tables/halloween2020.py b/royalpack/tables/halloween2020.py index 4782f06a..eb80a020 100644 --- a/royalpack/tables/halloween2020.py +++ b/royalpack/tables/halloween2020.py @@ -7,12 +7,12 @@ class Halloween2020: __tablename__ = "halloween2020" @declared_attr - def user_id(self): - return Column(Integer, ForeignKey("users.uid"), primary_key=True) + def _steamid(self): + return Column(BigInteger, ForeignKey("steam._steamid"), primary_key=True) @declared_attr - def user(self): - return relationship("User", backref=backref("halloween2020", uselist=False)) + def steam(self): + return relationship("Steam", backref=backref("halloween2020", uselist=False)) @declared_attr def zero(self): diff --git a/royalpack/tables/steam.py b/royalpack/tables/steam.py index 1e4fedbd..8b318002 100644 --- a/royalpack/tables/steam.py +++ b/royalpack/tables/steam.py @@ -76,7 +76,8 @@ class Steam: "most_played_game_forever": self.most_played_game_forever, "dota": self.dota.json() if self.dota is not None else None, - "brawlhalla": self.brawlhalla.json() if self.brawlhalla is not None else None + "brawlhalla": self.brawlhalla.json() if self.brawlhalla is not None else None, + "halloween2020": self.halloween2020.json() if self.halloween2020 is not None else None, } def __repr__(self): diff --git a/royalpack/types/halloween2020tarots.py b/royalpack/types/halloween2020tarots.py new file mode 100644 index 00000000..c3504972 --- /dev/null +++ b/royalpack/types/halloween2020tarots.py @@ -0,0 +1,168 @@ +from typing import * + + +class Halloween2020Tarot: + def __init__(self, + variable: str, + title: str, + roman: str, + name: str, + objective: str, + puzzle: str, + check: Optional[Callable[..., Awaitable[...]]]): + self.variable: str = variable + self.title: str = title + self.roman: str = roman + self.name: str = name + self.objective: str = objective + self.puzzle: str = puzzle + self.check: Optional[Callable[..., Awaitable[...]]] = check + + +halloween2020tarots = ( + Halloween2020Tarot( + variable="zero", + title="o", + roman="0", + name="Il Folle", + objective="Partecipa ai Trionfi Reali.", + puzzle="Scopri nuovi indizi ottenendo dei Trionfi!", + check=None, + ), + Halloween2020Tarot( + variable="i", + title="i", + roman="I", + name="Il Mago", + objective="Trova una magia che possa fare almeno 250 danni.", + puzzle="L'ultimo giorno del decimo mese...", + check=None, + ), + Halloween2020Tarot( + variable="ii", + title="ii", + roman="II", + name="La Papessa", + ), + Halloween2020Tarot( + variable="iii", + title="iii", + roman="III", + name="L'Imperatrice", + ), + Halloween2020Tarot( + variable="iv", + title="iv", + roman="IV", + name="L'Imperatore", + ), + Halloween2020Tarot( + variable="v", + title="v", + roman="V", + name="Il Papa", + ), + Halloween2020Tarot( + variable="vi", + title="vi", + roman="VI", + name="Gli Amanti", + objective="Completa [url=https://store.steampowered.com/app/698780]Doki Doki " + "Literature Club[/url].", + ), + Halloween2020Tarot( + variable="vii", + title="vii", + roman="VII", + name="Il Carro", + ), + Halloween2020Tarot( + variable="viii", + title="viii", + roman="VIII", + name="La Giustizia", + ), + Halloween2020Tarot( + variable="ix", + title="ix", + roman="IX", + name="L'Eremita", + ), + Halloween2020Tarot( + variable="x", + title="x", + roman="X", + name="La Fortuna", + ), + Halloween2020Tarot( + variable="xi", + title="xi", + roman="XI", + name="La Forza", + objective="Gioca 3 partite Ranked 1v1 su " + "[url=https://steamcommunity.com/id/steffo1999/stats/appid/291550/achievements]Brawlhalla[/url]." + ), + Halloween2020Tarot( + variable="xii", + title="xii", + roman="XII", + name="L'Appeso", + ), + Halloween2020Tarot( + variable="xiii", + title="xiii", + roman="XIII", + name="La Morte", + ), + Halloween2020Tarot( + variable="xiv", + title="xiv", + roman="XIV", + name="La Temperanza", + ), + Halloween2020Tarot( + variable="xv", + title="xv", + roman="XV", + name="Il Diavolo", + ), + Halloween2020Tarot( + variable="xvi", + title="xvi", + roman="XVI", + name="La Torre", + ), + Halloween2020Tarot( + variable="xvii", + title="xvii", + roman="XVII", + name="Le Stelle", + ), + Halloween2020Tarot( + variable="xviii", + title="xviii", + roman="XVIII", + name="La Luna", + ), + Halloween2020Tarot( + variable="xix", + title="xix", + roman="XIX", + name="Il Sole", + ), + Halloween2020Tarot( + variable="xx", + title="xx", + roman="XX", + name="Il Giudizio", + ), + Halloween2020Tarot( + variable="xxi", + title="xxi", + roman="XII", + name="Il Mondo", + objective="Risolvi il mistero dei Trionfi Reali.", + puzzle="""44°35'45.0"N 11°02'58.9"E""", + check=None, + ), +)