Esempio n. 1
0
    async def hod(self, context, recheck=True, channel_name: str = None):
        channel = (await self.get_channel(
            context,
            channel_name)) if channel_name else context.message.channel

        await channel.send("Checking raidlogs, back in a bit!")
        await self.monitor_clans(self.allclans)

        message = ""
        for raid in Raid.select().where(
                Raid.name == "dreadsylvania", Raid.end == None,
                Raid.clan_name == "The Hogs of Destiny"):
            message = "__**HOD BANISH STATUS**__ \n"
            for location in ["forest", "village", "castle"]:
                for element in [("stinky", "stench"), ("spooky", "spooky"),
                                ("sleazy", "sleaze"), ("hot", "hot"),
                                ("cold", "cold")]:
                    data = "{{\"element\": \"{}\", \"location\": \"{}\"}}".format(
                        element[0], location)
                    if not (location == "village"
                            and element[1] in ["spooky", "stench"]):
                        if not Log.select().where(
                                Log.raid == raid, Log.action
                                == RaidAction.DreadBanishElement, Log.data
                                == data).exists():
                            message += "{} banish needed in {} {} \n".format(
                                str(element[1]).capitalize(),
                                str(location).capitalize(),
                                banish_locations[(location, element[1])])
            village_banishes = [
                Log.select().where(
                    Log.raid == raid,
                    Log.action == RaidAction.DreadBanishElement, Log.data ==
                    "{\"element\": \"spooky\", \"location\": \"village\"}").
                exists(),
                Log.select().where(
                    Log.raid == raid,
                    Log.action == RaidAction.DreadBanishElement, Log.data ==
                    "{\"element\": \"stinky\", \"location\": \"village\"}").
                exists(),
                Log.select().where(
                    Log.raid == raid, Log.action == RaidAction.DreadBanishType,
                    Log.data ==
                    "{\"location\": \"village\", \"type\": \"ghosts\"}").count(
                    ),
                Log.select().where(
                    Log.raid == raid, Log.action == RaidAction.DreadBanishType,
                    Log.data ==
                    "{\"location\": \"village\", \"type\": \"zombies\"}").
                count()
            ]
            if village_banishes[0]:
                if village_banishes[2] < 2:
                    message += "{} ghost banish{} still needed. \n".format(
                        "One" if village_banishes[2] else "Two",
                        "" if village_banishes[2] else "es")

            elif village_banishes[1]:
                if village_banishes[3] < 2:
                    message += "{} zombie banish{} still needed. \n".format(
                        "One" if village_banishes[3] else "Two",
                        "" if village_banishes[3] else "es")

            elif village_banishes[2]:
                message += "{} banish needed in {} {} \n".format(
                    "Spooky", "Village",
                    banish_locations[("village", "spooky")])
                if village_banishes[3] < 2:
                    message += "One ghost banish still needed. \n"

            elif village_banishes[3]:
                message += "{} banish needed in {} {} \n".format(
                    "Stench", "Village",
                    banish_locations[("village", "stench")])
                if village_banishes[3] < 2:
                    message += "One zombie banish still needed. \n"

            else:
                message += "Couldn't tell if this is a spooky ghost or a stench zombie instance. \n"
                message += "Either banish spooky {} or stench {} from the village. \n".format(
                    banish_locations[("village", "spooky")],
                    banish_locations[("village", "stench")])
            if message == "__**HOD BANISH STATUS**__ \n":
                message += "All banishes complete. \n"
            message += "(You may also want to run !clan hod)"
        if channel_name:
            await context.send("Sending summary to {}".format(channel.name))
        await channel.send(message)
Esempio n. 2
0
    async def summary(self,
                      context,
                      recheck=True,
                      send_message=True,
                      channel_name: str = None,
                      description: str = None):
        """
        Post a summary of all the Dreadsylvania instances currently being monitored.

        :param channel_name: Channel to post the summary to. If not specified, the bot will respond
                             to you in a PM
        :param description: Text to appear inline with the summary.
        :return:
        """
        channel = (await self.get_channel(
            context,
            channel_name)) if channel_name else context.message.channel

        if recheck:
            await channel.send("Checking raidlogs, back in a bit!")
            await self.monitor_clans(self.clans)

        message = "__DREAD STATUS__\n"

        if description is not None:
            message += "{}\n\n".format(description)

        for raid in Raid.select().where(
                Raid.name == "dreadsylvania", Raid.end == None,
                Raid.clan_name << [x[0] for x in self.clans]):
            skip_clan = False
            for clan in excluded_clans:
                if raid.clan_id in clan:
                    skip_clan = True
            if skip_clan is True:
                print("Skipping " + raid.clan_name)
                continue
            else:
                summary = json.loads(raid.summary)

                kills = {"forest": 1000, "village": 1000, "castle": 1000}

                for line in summary:
                    m = kills_pattern.match(line.replace(",", ""))
                    if m:
                        kills[m.group(2).lower()] -= int(m.group(1))

                extra = None
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadMachineFix).exists():
                    machine_uses = Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadMachineUse).count()
                    left = 3 - machine_uses
                    extra = " ({} skill{} left)".format(
                        left, "" if left == 1 else "s")
                else:
                    extra = " (needs capacitor)"

                message += "**{}**: {}/{}/{}{}\n".format(
                    raid.clan_name, kills["forest"], kills["village"],
                    kills["castle"], extra or "")
        message += "\n"

        if channel_name:
            await context.send("Sending summary to {}".format(channel.name))
        if send_message:
            await channel.send(message)
        else:
            return message
Esempio n. 3
0
    async def clan(self,
                   context,
                   clanname,
                   recheck=True,
                   send_message=True,
                   channel_name: str = None):
        channel = (await self.get_channel(
            context,
            channel_name)) if channel_name else context.message.channel

        tocheck = None
        for clan in self.allclans:
            if clanname.lower() in clan[0].lower() or clanname.lower(
            ) in clan[2]:
                tocheck = clan
                break

        if recheck:
            await channel.send("Checking raidlogs, back in a bit!")
            await self.monitor_clans([tocheck])

        message = ""
        for raid in Raid.select().where(Raid.name == "dreadsylvania",
                                        Raid.end == None,
                                        Raid.clan_name == tocheck[0]):
            message = "__**STATUS UPDATE FOR {}**__ \n".format(
                tocheck[0].upper())
            summary = json.loads(raid.summary)

            kills = {"forest": 1000, "village": 1000, "castle": 1000}

            for line in summary:
                m = kills_pattern.match(line.replace(",", ""))
                if m:
                    kills[m.group(2).lower()] -= int(m.group(1))
            message += "{}/{}/{} kills remaining\n\n".format(
                kills["forest"], kills["village"], kills["castle"])
            message += "__FOREST__ \n"
            if kills["forest"]:
                if not Log.select().where(
                        Log.raid == raid, Log.action == RaidAction.DreadUnlock,
                        Log.data
                        == "{\"location\": \"attic of the cabin\"}").exists():
                    message += "**Cabin attic needs unlocking** \n"
                if Log.select().where(
                        Log.raid == raid, Log.action == RaidAction.DreadUnlock,
                        Log.data ==
                        "{\"location\": \"fire watchtower\"}").exists():
                    message += "Watchtower open, you can grab freddies if you like \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem, Log.data ==
                        "{\"item\": \"Dreadsylvanian auditor's badge\"}"
                ).exists():
                    message += "~~Auditor's badge claimed~~ \n"
                else:
                    message += "Auditor's badge available (Cabin -> Basement -> Lockbox) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadBanishElement,
                        Log.data ==
                        "{\"element\": \"spooky\", \"location\": \"forest\"}"
                ).exists():
                    message += "~~Intricate music box parts claimed~~ \n"
                else:
                    message += "Intricate music box parts available (Cabin -> Attic -> Music Box as AT (also banishes spooky from forest)) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem,
                        Log.data == "{\"item\": \"blood kiwi\"}").exists():
                    message += "~~Blood kiwi claimed~~ \n"
                else:
                    message += "Blood kiwi available (Tree, Root Around -> Look Up + Climb -> Stomp) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem, Log.data ==
                        "{\"item\": \"chunk of moon-amber\"}").exists():
                    message += "~~Moon-amber claimed~~ \n"
                else:
                    message += "Moon-amber available (Tree -> Climb -> Shiny Thing (requires muscle class)) \n"
            else:
                message += "~~Forest fully cleared~~ \n"

            message += "__VILLAGE__ \n"
            if kills["village"]:
                if Log.select().where(
                        Log.raid == raid, Log.action == RaidAction.DreadUnlock,
                        Log.data ==
                        "{\"location\": \"schoolhouse\"}").exists():
                    message += "Schoolhouse is open, go get your pencils! \n"
                if Log.select().where(
                        Log.raid == raid, Log.action == RaidAction.DreadUnlock,
                        Log.data ==
                        "{\"location\": \"master suite\"}").exists():
                    message += "Master suite is open, grab some eau de mort? \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadHangee).exists():
                    message += "~~Hanging complete~~ \n"
                else:
                    message += "Hanging available (Square, Gallows -> Stand on Trap Door + Gallows -> Pull Lever) \n"
            else:
                message += "~~Village fully cleared~~ \n"

            message += "__CASTLE__ \n"
            if kills["castle"]:
                if not Log.select().where(
                        Log.raid == raid, Log.action == RaidAction.DreadUnlock,
                        Log.data == "{\"location\": \"lab\"}").exists():
                    message += "**Lab needs unlocking** \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadMachineFix).exists():
                    machine_uses = Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadMachineUse).count()
                    left = 3 - machine_uses
                    if left:
                        message += "{} skill{} available.\n".format(
                            left, "" if left == 1 else "s")
                    else:
                        message += "~~All skills claimed~~ \n"
                else:
                    message += "Machine needs repairing (with skull capacitor) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem,
                        Log.data == "{\"item\": \"roast beast\"}").exists():
                    message += "~~Dreadful roast claimed~~ \n"
                else:
                    message += "Dreadful roast available (Great Hall -> Dining Room -> Grab roast) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem,
                        Log.data == "{\"item\": \"wax banana\"}").exists():
                    message += "~~Wax banana claimed~~ \n"
                else:
                    message += "Wax banana available (Great Hall -> Dining Room -> Levitate (requires myst class) \n"
                if Log.select().where(
                        Log.raid == raid,
                        Log.action == RaidAction.DreadGotItem, Log.data ==
                        "{\"item\": \"stinking agaric\"}").exists():
                    message += "~~Stinking agaricus claimed~~ \n"
                else:
                    message += "Stinking agaricus available (Dungeons -> Guard Room -> Break off bits) \n"
            else:
                message += "~~Castle fully cleared~~ \n"

        if channel_name:
            await context.send("Sending summary to {}".format(channel.name))
        if send_message:
            await channel.send(message)
        else:
            return message
Esempio n. 4
0
    async def skills(self,
                     context,
                     recheck=True,
                     send_message=True,
                     since: str = "2019-06-06",
                     limit: int = None,
                     channel_name: str = None):
        channel = await self.get_channel(
            context, channel_name) if channel_name else context.channel

        if recheck:
            await channel.send("Checking raidlogs, back in a bit!")
            await self.monitor_clans(self.clans)

        since = datetime.strptime(
            since,
            "%Y-%m-%d") if since is not None else datetime.now() - timedelta(
                days=365)

        if limit is None:
            limit = len(self.clans) * 3
        elif limit == 0:
            limit = None

        Skills = Log.alias()

        skills_query = Skills.select(Skills.user_id,
                                     (fn.COUNT(Skills.id) + (fn.IFNULL(PriorActivity.skills, 0))).alias("skills"))\
                             .join_from(Skills, PriorActivity, JOIN.LEFT_OUTER, on=(Skills.user_id == PriorActivity.id))\
                             .join_from(Skills, Raid)\
                             .where(Skills.action == RaidAction.DreadMachineUse, Raid.start >= since, Raid.clan_name << [x[0] for x in self.clans])\
                             .group_by(Skills.user_id)\
                             .alias("sq")

        right_joined_skills_query = PriorActivity.select((PriorActivity.id).alias("user_id"),
                                    (fn.IFNULL(PriorActivity.skills, skills_query.c.skills)).alias("skills"))\
                            .join_from(PriorActivity, skills_query, JOIN.LEFT_OUTER, on=(skills_query.c.user_id == PriorActivity.id))

        skills_query = skills_query | right_joined_skills_query  #DIY FULL OUTER JOIN

        kills_query = Log.select(Log.user_id,
                                 Log.username.alias("Username"),
                                 (fn.SUM(Log.turns)+ (fn.IFNULL(PriorActivity.kills, 0))).alias("kills"))\
                         .join_from(Log, PriorActivity, JOIN.LEFT_OUTER, on=(Log.user_id == PriorActivity.id))\
                         .join_from(Log, Raid)\
                         .where(Log.action == RaidAction.Victory, Raid.name == "dreadsylvania", Raid.start >= since, Raid.clan_name in [x[0] for x in self.clans])\
                         .group_by(Log.user_id)

        rankings_query = Log.select(kills_query.c.username.alias("Username"),
                                            kills_query.c.kills.alias("Kills"),
                                            fn.IFNULL(skills_query.c.skills, 0).alias("Skills"),
                                            (kills_query.c.kills / (fn.IFNULL(skills_query.c.skills, 0) + 0.5)).alias("KillsPerSkill"))\
                                    .join_from(Log, skills_query, JOIN.LEFT_OUTER, on=(Log.user_id == skills_query.c.user_id))\
                                    .join_from(Log, kills_query, JOIN.LEFT_OUTER, on=(Log.user_id == kills_query.c.user_id))\
                                    .group_by(kills_query.c.user_id)\
                                    .order_by(SQL("KillsPerSkill").desc())\

        rankings = [
            x for x in [r for r in rankings_query.dicts()]
            if x["Username"] and not x["Username"].lower() in excluded_list
        ]
        table = tabulate(rankings, headers="keys")
        table = table[:1900]
        message = "__SKILL RANKINGS__ \n```\n{}\n```".format(table)

        if channel_name:
            await context.send("Sending skills to {}".format(channel.name))
        if send_message:
            await channel.send(message)
        else:
            return message