Esempio n. 1
0
    async def check_team_goals(self, bot: Red) -> None:
        """
        Checks to see if a goal needs to be posted
        """
        team_data = {
            self.home_team: await get_team(bot, self.home_team),
            self.away_team: await get_team(bot, self.away_team),
        }
        # home_team_data = await get_team(bot, self.home_team)
        # away_team_data = await get_team(bot, self.away_team)
        # all_data = await get_team("all")
        team_list = await bot.get_cog("Hockey").config.teams()
        # post_state = ["all", self.home_team, self.away_team]

        # home_goal_ids = [goal.goal_id for goal in self.home_goals]
        # away_goal_ids = [goal.goal_id for goal in self.away_goals]

        home_goal_list = list(team_data[self.home_team]["goal_id"])
        away_goal_list = list(team_data[self.away_team]["goal_id"])

        for goal in self.goals:
            # goal_id = str(goal["result"]["eventCode"])
            # team = goal["team"]["name"]
            # team_data = await get_team(bot, goal.team_name)
            if goal.goal_id not in team_data[goal.team_name]["goal_id"]:
                # attempts to post the goal if there is a new goal
                bot.dispatch("hockey_goal", self, goal)
                goal.home_shots = self.home_shots
                goal.away_shots = self.away_shots
                msg_list = await goal.post_team_goal(bot, self)
                team_list.remove(team_data[goal.team_name])
                team_data[goal.team_name]["goal_id"][goal.goal_id] = {
                    "goal": goal.to_json(),
                    "messages": msg_list,
                }
                team_list.append(team_data[goal.team_name])
                await bot.get_cog("Hockey").config.teams.set(team_list)
                continue
            if goal.goal_id in team_data[goal.team_name]["goal_id"]:
                # attempts to edit the goal if the scorers have changed
                old_goal = Goal(**team_data[goal.team_name]["goal_id"][goal.goal_id]["goal"])
                if goal.description != old_goal.description or goal.link != old_goal.link:
                    goal.home_shots = old_goal.home_shots
                    goal.away_shots = old_goal.away_shots
                    # This is to keep shots consistent between edits
                    # Shots should not update as the game continues
                    bot.dispatch("hockey_goal_edit", self, goal)
                    old_msgs = team_data[goal.team_name]["goal_id"][goal.goal_id]["messages"]
                    team_list.remove(team_data[goal.team_name])
                    team_data[goal.team_name]["goal_id"][goal.goal_id]["goal"] = goal.to_json()
                    team_list.append(team_data[goal.team_name])
                    await bot.get_cog("Hockey").config.teams.set(team_list)
                    await goal.edit_team_goal(bot, self, old_msgs)
        # attempts to delete the goal if it was called back
        for goal_str in home_goal_list:
            await Goal.remove_goal_post(bot, goal_str, self.home_team, self)
        for goal_str in away_goal_list:
            await Goal.remove_goal_post(bot, goal_str, self.away_team, self)
Esempio n. 2
0
    async def post_game_state(self, bot: Red) -> None:
        """
        When a game state has changed this is called to create the embed
        and post in all channels
        """
        post_state = ["all", self.home_team, self.away_team]
        state_embed = await self.game_state_embed()
        state_text = await self.game_state_text()
        tasks = []
        all_channels = await bot.get_cog("Hockey").config.all_channels()
        async for channel_id, data in AsyncIter(all_channels.items(), steps=100):
            channel = await get_channel_obj(bot, channel_id, data)
            if not channel:
                continue

            should_post = await check_to_post(bot, channel, data, post_state, self.game_state)
            if should_post:
                tasks.append(self.actually_post_state(bot, channel, state_embed, state_text))
        previews = await bounded_gather(*tasks)
        for preview in previews:
            if preview is None:
                continue
            else:
                bot.dispatch("hockey_preview_message", preview[0], preview[1], self)
Esempio n. 3
0
    async def actually_post_state(
        self, bot: Red, channel: discord.TextChannel, state_embed: discord.Embed, state_text: str
    ) -> Optional[Tuple[discord.TextChannel, discord.Message]]:
        guild = channel.guild
        if not channel.permissions_for(guild.me).send_messages:
            log.debug("No permission to send messages in %s", repr(channel))
            return None
        config = bot.get_cog("Hockey").config
        guild_settings = await config.guild(guild).all()
        channel_settings = await config.channel(channel).all()
        game_day_channels = guild_settings["gdc"]
        can_embed = channel.permissions_for(guild.me).embed_links
        publish_states = []  # await config.channel(channel).publish_states()
        # can_manage_webhooks = False  # channel.permissions_for(guild.me).manage_webhooks

        if self.game_state == "Live":

            guild_notifications = guild_settings["game_state_notifications"]
            channel_notifications = channel_settings["game_state_notifications"]
            state_notifications = guild_notifications or channel_notifications
            # TODO: Something with these I can't remember what now
            # guild_start = guild_settings["start_notifications"]
            # channel_start = channel_settings["start_notifications"]
            # start_notifications = guild_start or channel_start
            # heh inclusive or
            allowed_mentions = {}
            home_role, away_role = await get_team_role(guild, self.home_team, self.away_team)
            if version_info >= VersionInfo.from_str("3.4.0"):
                if state_notifications:
                    allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=True)}
                else:
                    allowed_mentions = {"allowed_mentions": discord.AllowedMentions(roles=False)}
            if self.game_type == "R" and "OT" in self.period_ord:
                if not guild_settings["ot_notifications"]:
                    if version_info >= VersionInfo.from_str("3.4.0"):
                        allowed_mentions = {
                            "allowed_mentions": discord.AllowedMentions(roles=False)
                        }
                    else:
                        allowed_mentions = {}
            if "SO" in self.period_ord:
                if not guild_settings["so_notifications"]:
                    if version_info >= VersionInfo.from_str("3.4.0"):
                        allowed_mentions = {
                            "allowed_mentions": discord.AllowedMentions(roles=False)
                        }
                    else:
                        allowed_mentions = {}
            if game_day_channels is not None:
                # We don't want to ping people in the game day channels twice
                if channel.id in game_day_channels:
                    home_role, away_role = self.home_team, self.away_team
            msg = _("**{period} Period starting {away_role} at {home_role}**").format(
                period=self.period_ord, away_role=away_role, home_role=home_role
            )
            try:
                if not can_embed:
                    msg = await channel.send(msg + "\n{}".format(state_text), **allowed_mentions)
                else:
                    msg = await channel.send(msg, embed=state_embed, **allowed_mentions)
                if self.game_state in publish_states:
                    try:
                        if channel.is_news():
                            # allows backwards compatibility still
                            # await msg.publish()
                            pass
                    except Exception:
                        pass
            except Exception:
                log.exception("Could not post goal in %s", repr(channel))

        else:
            if self.game_state == "Preview":
                if game_day_channels is not None:
                    # Don't post the preview message twice in the channel
                    if channel.id in game_day_channels:
                        return None
            try:
                if not can_embed:
                    preview_msg = await channel.send(state_text)
                else:
                    preview_msg = await channel.send(embed=state_embed)

                if self.game_state in publish_states:
                    try:
                        if channel.is_news():
                            # allows backwards compatibility still
                            # await preview_msg.publish()
                            pass
                    except Exception:
                        pass

                # Create new pickems object for the game
                if self.game_state == "Preview":
                    bot.dispatch("hockey_preview_message", channel, preview_msg, self)
                    if channel.permissions_for(guild.me).add_reactions:
                        try:
                            await preview_msg.add_reaction(self.away_emoji[2:-1])
                            await preview_msg.add_reaction(self.home_emoji[2:-1])
                        except Exception:
                            log.debug("Could not add reactions")
                        return channel, preview_msg
            except Exception:
                log.exception("Could not post goal in %s", repr(channel))
        return None
Esempio n. 4
0
    async def check_game_state(self, bot: Red, count: int = 0) -> bool:
        # post_state = ["all", self.home_team, self.away_team]
        home = await get_team(bot, self.home_team)
        # away = await get_team(self.away_team)
        # team_list = await self.config.teams()
        # Home team checking
        end_first = self.period_time_left == "END" and self.period == 1
        end_second = self.period_time_left == "END" and self.period == 2
        end_third = self.period_time_left == "END" and self.period == 3
        if self.game_state == "Preview":
            """Checks if the the game state has changes from Final to Preview
            Could be unnecessary since after Game Final it will check for next game
            """
            time_now = datetime.now(tz=timezone.utc)
            # game_time = datetime.strptime(data.game_start, "%Y-%m-%dT%H:%M:%SZ")
            game_start = (self.game_start - time_now).total_seconds() / 60
            if "Preview" not in home["game_state"]:
                await self.post_game_state(bot)
                await self.save_game_state(bot)
                bot.dispatch("hockey_preview", self)
            if game_start < 60 and game_start > 30 and home["game_state"] != "Preview60":
                # Post 60 minutes until game start
                await self.post_time_to_game_start(bot, "60")
                await self.save_game_state(bot, "60")
                bot.dispatch("hockey_preview", self)
            if game_start < 30 and game_start > 10 and home["game_state"] != "Preview30":
                # Post 30 minutes until game start
                await self.post_time_to_game_start(bot, "30")
                await self.save_game_state(bot, "30")
                bot.dispatch("hockey_preview", self)
            if game_start < 10 and game_start > 0 and home["game_state"] != "Preview10":
                # Post 10 minutes until game start
                await self.post_time_to_game_start(bot, "10")
                await self.save_game_state(bot, "10")
                bot.dispatch("hockey_preview", self)

                # Create channel and look for game day thread

        if self.game_state == "Live":
            # Checks what the period is and posts the game is starting in the appropriate channel

            if home["period"] != self.period or "Preview" in home["game_state"]:
                log.debug(
                    "**%s Period starting %s at %s**",
                    self.period_ord,
                    self.away_team,
                    self.home_team,
                )
                await self.post_game_state(bot)
                await self.save_game_state(bot)
                bot.dispatch("hockey_period_start", self)

            if (self.home_score + self.away_score) != 0:
                # Check if there's goals only if there are goals
                await self.check_team_goals(bot)
            if end_first and home["game_state"] != "LiveEND1st":
                log.debug("End of the first period")
                await self.period_recap(bot, "1st")
                await self.save_game_state(bot, "END1st")
            if end_second and home["game_state"] != "LiveEND2nd":
                log.debug("End of the second period")
                await self.period_recap(bot, "2nd")
                await self.save_game_state(bot, "END2nd")
            if end_third and home["game_state"] not in ["LiveEND3rd", "FinalEND3rd"]:
                log.debug("End of the third period")
                await self.period_recap(bot, "3rd")
                await self.save_game_state(bot, "END3rd")

        if self.game_state == "Final":
            if end_third and home["game_state"] not in ["LiveEND3rd", "FinalEND3rd"]:
                log.debug("End of the third period")
                await self.period_recap(bot, "3rd")
                await self.save_game_state(bot, "END3rd")

        if self.game_state == "Final" and (self.first_star is not None or count >= 10):
            """Final game state checks"""

            if (self.home_score + self.away_score) != 0:
                # Check for goal before posting game final, happens with OT games
                await self.check_team_goals(bot)
                log.debug("Checking team goals for the last time")

            if home["game_state"] != self.game_state and home["game_state"] != "Null":

                # Post game final data and check for next game
                log.debug("Game Final %s @ %s", self.away_team, self.home_team)
                await self.post_game_state(bot)
                await self.save_game_state(bot)
                bot.dispatch("hockey_final", self)
                log.debug("Saving final")
                return True
        return False