コード例 #1
0
ファイル: alias_controller.py プロジェクト: Budabot/Tyrbot
class AliasController:
    def inject(self, registry):
        self.command_alias_service = registry.get_instance("command_alias_service")
        self.text = registry.get_instance("text")

    @command(command="alias", params=[Const("list")], access_level="all",
             description="List command aliases")
    def alias_list_cmd(self, request, _):
        data = self.command_alias_service.get_enabled_aliases()
        count = len(data)
        padded_rows = self.text.pad_table(list(map(lambda row: [row.alias, row.command], data)))

        blob = ""
        for cols in padded_rows:
            blob += "  ".join(cols) + "\n"

        return ChatBlob(f"Aliases ({count})", blob)

    @command(command="alias", params=[Const("add"), Any("alias"), Any("command")], access_level="admin",
             description="Add a command alias", sub_command="modify")
    def alias_add_cmd(self, request, _, alias, command_str):
        if self.command_alias_service.add_alias(alias, command_str, force_enable=True):
            return f"Alias <highlight>{alias}</highlight> for command <highlight>{command_str}</highlight> added successfully."
        else:
            return f"Cannot add alias <highlight>{alias}</highlight> since there is already an active alias with that name."

    @command(command="alias", params=[Options(["rem", "remove"]), Any("alias")], access_level="admin",
             description="Remove a command alias", sub_command="modify")
    def alias_remove_cmd(self, request, _, alias):
        if self.command_alias_service.remove_alias(alias):
            return f"Alias <highlight>{alias}</highlight> has been removed successfully."
        else:
            return f"Could not find alias <highlight>{alias}</highlight>."
コード例 #2
0
class TopicController:
    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util = registry.get_instance("util")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")

    def start(self):
        self.command_alias_service.add_alias("motd", "topic")

    @setting(name="topic", value="", description="The bot topic")
    def topic(self):
        return DictionarySettingType()

    @command(command="topic",
             params=[],
             access_level="all",
             description="Show the current topic")
    def topic_show_command(self, request):
        topic = self.topic().get_value()
        if topic:
            time_string = self.util.time_to_readable(
                int(time.time()) - topic["created_at"])
            return "Topic: <highlight>%s<end> [set by <highlight>%s<end>][%s ago]" % (
                topic["topic_message"], topic["created_by"]["name"],
                time_string)
        else:
            return "There is no current topic."

    @command(command="topic",
             params=[Options(["clear", "unset"])],
             access_level="all",
             description="Clears the current topic")
    def topic_clear_command(self, request, _):
        self.topic().set_value("")

        return "The topic has been cleared."

    @command(command="topic",
             params=[Const("set", is_optional=True),
                     Any("topic_message")],
             access_level="all",
             description="Set the current topic")
    def topic_set_command(self, request, _, topic_message):
        sender = DictObject({
            "name": request.sender.name,
            "char_id": request.sender.char_id
        })

        topic = {
            "topic_message": topic_message,
            "created_by": sender,
            "created_at": int(time.time())
        }

        self.topic().set_value(topic)

        return "The topic has been set."
コード例 #3
0
class AliasController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.command_alias_manager = registry.get_instance(
            "command_alias_manager")

    def start(self):
        pass

    @command(command="alias",
             params=[Const("list")],
             access_level="all",
             description="List command aliases")
    def alias_list_cmd(self, channel, sender, reply, args):
        blob = ""
        data = self.command_alias_manager.get_enabled_aliases()
        count = len(data)
        for row in data:
            blob += row.alias + " - " + row.command + "\n"

        reply(ChatBlob("Aliases (%d)" % count, blob))

    @command(command="alias",
             params=[Const("add"), Any("alias"),
                     Any("command")],
             access_level="superadmin",
             description="Add a command alias",
             sub_command="modify")
    def alias_add_cmd(self, channel, sender, reply, args):
        alias = args[1]
        command = args[2]
        if self.command_alias_manager.add_alias(alias, command):
            reply(
                "Alias <highlight>%s<end> for command <highlight>%s<end> added successfully."
                % (alias, command))
        else:
            reply(
                "Cannot add alias <highlight>%s<end> since there is already an active alias with that name."
                % alias)

    @command(command="alias",
             params=[Options(["rem", "remove"]),
                     Any("alias")],
             access_level="superadmin",
             description="Remove a command alias",
             sub_command="modify")
    def alias_remove_cmd(self, channel, sender, reply, args):
        alias = args[1]
        if self.command_alias_manager.remove_alias(alias):
            reply("Alias <highlight>%s<end> has been removed successfully." %
                  alias)
        else:
            reply("Could not find alias <highlight>%s<end>." % alias)
コード例 #4
0
ファイル: alias_controller.py プロジェクト: deathlef/Tyrbot
class AliasController:
    def inject(self, registry):
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.ts: TranslationService = registry.get_instance(
            "translation_service")
        self.getresp = self.ts.get_response

    @command(command="alias",
             params=[Const("list")],
             access_level="all",
             description="List command aliases")
    def alias_list_cmd(self, request, _):
        blob = ""
        data = self.command_alias_service.get_enabled_aliases()
        count = len(data)
        for row in data:
            blob += row.alias + " - " + row.command + "\n"

        return ChatBlob(
            self.getresp("module/config", "alias_blob_title",
                         {"amount": count}), blob)

    @command(command="alias",
             params=[Const("add"), Any("alias"),
                     Any("command")],
             access_level="admin",
             description="Add a command alias",
             sub_command="modify")
    def alias_add_cmd(self, request, _, alias, command_str):
        if self.command_alias_service.add_alias(alias,
                                                command_str,
                                                force_enable=True):
            return self.getresp("module/config", "alias_add_success", {
                "alias": alias,
                "cmd": command_str
            })
        else:
            return self.getresp("module/config", "alias_add_fail",
                                {"alias": alias})

    @command(command="alias",
             params=[Options(["rem", "remove"]),
                     Any("alias")],
             access_level="admin",
             description="Remove a command alias",
             sub_command="modify")
    def alias_remove_cmd(self, request, _, alias):
        if self.command_alias_service.remove_alias(alias):
            return self.getresp("module/config", "alias_rem_success",
                                {"alias": alias})
        else:
            return self.getresp("module/config", "alias_rem_fail",
                                {"alias": alias})
コード例 #5
0
ファイル: notes_controller.py プロジェクト: fatpower/Tyrbot-1
class NotesController:
    def inject(self, registry):
        self.db = registry.get_instance("db")
        self.text = registry.get_instance("text")
        self.alts_service = registry.get_instance("alts_service")

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS notes ("
                     "id INT PRIMARY KEY AUTO_INCREMENT, "
                     "char_id INT NOT NULL, "
                     "note TEXT NOT NULL,"
                     "created_at INT NOT NULL)")

    @command(command="notes", params=[], access_level="all",
             description="Show your notes")
    def notes_list_cmd(self, request):
        alts = self.alts_service.get_alts(request.sender.char_id)

        cnt = 0
        blob = ""
        for alt in alts:
            data = self.db.query("SELECT * FROM notes WHERE char_id = ? ORDER BY created_at DESC", [alt.char_id])
            alt_cnt = len(data)
            cnt += alt_cnt

            if alt_cnt:
                blob += "\n<header2>%s<end>\n" % alt.name
                for row in data:
                    blob += "%s %s\n\n" % (row.note, self.text.make_chatcmd("Remove", "/tell <myname> notes remove %d" % row.id))

        return ChatBlob("Notes for %s (%d)" % (alts[0].name, cnt), blob)

    @command(command="notes", params=[Const("add"), Any("note")], access_level="all",
             description="Add a note")
    def notes_add_cmd(self, request, _, note):
        self.db.exec("INSERT INTO notes (char_id, note, created_at) VALUES (?, ?, ?)", [request.sender.char_id, note, int(time.time())])

        return "Note added successfully."

    @command(command="notes", params=[Options(["rem", "remove"]), Int("note_id")], access_level="all",
             description="Remove a note")
    def notes_remove_cmd(self, request, _, note_id):
        note = self.db.query_single("SELECT n.*, p.name FROM notes n LEFT JOIN player p ON n.char_id = p.char_id WHERE n.id = ?", [note_id])

        if not note:
            return "Could not find note with ID <highlight>%d<end>." % note_id

        if self.alts_service.get_main(request.sender.char_id).char_id != self.alts_service.get_main(note.char_id).char_id:
            return "You must be a confirmed alt of <highlight>%s<end> to remove this note." % note.name

        self.db.exec("DELETE FROM notes WHERE id = ?", [note_id])

        return "Note with ID <highlight>%d<end> deleted successfully." % note_id
コード例 #6
0
class BanController:
    def inject(self, registry):
        self.text = registry.get_instance("text")
        self.util = registry.get_instance("util")
        self.ban_service = registry.get_instance("ban_service")
        self.command_alias_service = registry.get_instance("command_alias_service")

    def start(self):
        self.command_alias_service.add_alias("unban", "ban rem")

    @command(command="ban", params=[Const("list", is_optional=True)], access_level="moderator",
             description="Show the ban list")
    def ban_list_cmd(self, request, _):
        t = int(time.time())
        data = self.ban_service.get_ban_list()
        blob = ""
        for row in data:
            ends = "never" if row.finished_at == -1 else self.util.format_timestamp(row.finished_at)
            time_left = "" if row.finished_at == -1 else " (%s left)" % self.util.time_to_readable(row.finished_at - t)

            blob += "<pagebreak>Name: <highlight>%s<end>\n" % row.name
            blob += "Added: <highlight>%s<end>\n" % self.util.format_timestamp(row.created_at)
            blob += "By: <highlight>%s<end>\n" % row.sender_name
            blob += "Ends: <highlight>%s<end>%s\n" % (ends, time_left)
            blob += "Reason: <highlight>%s<end>\n\n" % row.reason

        return ChatBlob("Ban List (%d)" % len(data), blob)

    @command(command="ban", params=[Options(["rem", "remove"]), Character("character")], access_level="moderator",
             description="Remove a character from the ban list")
    def ban_remove_cmd(self, request, _, char):
        if not char.char_id:
            return "Could not find <highlight>%s<end>." % char.name
        elif not self.ban_service.get_ban(char.char_id):
            return "<highlight>%s<end> is not banned." % char.name
        else:
            self.ban_service.remove_ban(char.char_id)
            return "<highlight>%s<end> has been removed from the ban list." % char.name

    @command(command="ban", params=[Const("add", is_optional=True), Character("character"), Time("duration", is_optional=True), Any("reason", is_optional=True)], access_level="moderator",
             description="Add a character to the ban list")
    def ban_add_cmd(self, request, _, char, duration, reason):
        reason = reason or ""

        if not char.char_id:
            return "Could not find <highlight>%s<end>." % char.name
        elif self.ban_service.get_ban(char.char_id):
            return "<highlight>%s<end> is already banned." % char.name
        else:
            self.ban_service.add_ban(char.char_id, request.sender.char_id, duration, reason)
            return "<highlight>%s<end> has been added to the ban list." % char.name
コード例 #7
0
class LinksController:
    def inject(self, registry):
        self.db = registry.get_instance("db")
        self.text = registry.get_instance("text")

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS links ("
                     "id INT PRIMARY KEY AUTO_INCREMENT,"
                     "char_id INT NOT NULL,"
                     "website VARCHAR(255) NOT NULL,"
                     "comments VARCHAR(255) NOT NULL,"
                     "created_at INT NOT NULL);")

    @command(command="links", params=[], access_level="all",
             description="Show links")
    def links_list_cmd(self, request):
        data = self.db.query("SELECT l.*, p.name FROM links l LEFT JOIN player p ON l.char_id = p.char_id ORDER BY name ASC")

        blob = ""
        for row in data:
            blob += "%s <highlight>%s<end> [%s] %s" % (self.text.make_chatcmd("[Link]", "/start %s" % row.website),
                                                       row.comments,
                                                       row.name,
                                                       self.text.make_chatcmd("Remove", "/tell <myname> links remove %d" % row.id))

        return ChatBlob("Links (%d)" % len(data), blob)

    @command(command="links", params=[Const("add"), Any("website"), Any("comment")], access_level="moderator",
             description="Add a link")
    def links_add_cmd(self, request, _, website, comment):
        if not website.startswith("https://") and not website.startswith("http://"):
            return "Website must start with 'http://' or 'https://'."

        self.db.exec("INSERT INTO links (char_id, website, comments, created_at) VALUES (?, ?, ?, ?)", [request.sender.char_id, website, comment, int(time.time())])
        return "Link added successfully."

    @command(command="links", params=[Options(["rem", "remove"]), Int("link_id")], access_level="moderator",
             description="Remove a link")
    def links_remove_cmd(self, request, _, link_id):
        link = self.db.query_single("SELECT * FROM links WHERE id = ?", [link_id])
        if not link:
            return "Could not find link with ID <highlight>%d<end>." % link_id

        self.db.exec("DELETE FROM links WHERE id = ?", [link_id])
        return "Link has been deleted"
コード例 #8
0
ファイル: alias_controller.py プロジェクト: wowpin/Tyrbot
class AliasController:
    def inject(self, registry):
        self.command_alias_service = registry.get_instance(
            "command_alias_service")

    @command(command="alias",
             params=[Const("list")],
             access_level="all",
             description="List command aliases")
    def alias_list_cmd(self, request, _):
        blob = ""
        data = self.command_alias_service.get_enabled_aliases()
        count = len(data)
        for row in data:
            blob += row.alias + " - " + row.command + "\n"

        return ChatBlob("Aliases (%d)" % count, blob)

    @command(command="alias",
             params=[Const("add"), Any("alias"),
                     Any("command")],
             access_level="admin",
             description="Add a command alias",
             sub_command="modify")
    def alias_add_cmd(self, request, _, alias, command_str):
        if self.command_alias_service.add_alias(alias,
                                                command_str,
                                                force_enable=True):
            return "Alias <highlight>%s<end> for command <highlight>%s<end> added successfully." % (
                alias, command_str)
        else:
            return "Cannot add alias <highlight>%s<end> since there is already an active alias with that name." % alias

    @command(command="alias",
             params=[Options(["rem", "remove"]),
                     Any("alias")],
             access_level="admin",
             description="Remove a command alias",
             sub_command="modify")
    def alias_remove_cmd(self, request, _, alias):
        if self.command_alias_service.remove_alias(alias):
            return "Alias <highlight>%s<end> has been removed successfully." % alias
        else:
            return "Could not find alias <highlight>%s<end>." % alias
コード例 #9
0
class LangController:
    def inject(self, registry):
        self.ts = registry.get_instance("translation_service")
        self.bot: Tyrbot = registry.get_instance("bot")

    @command(command="lang",
             params=[Options(["de_DE", "en_US"])],
             description="Changes the language of the bot",
             access_level="moderator",
             sub_command="set")
    def reload_translation(self, request, lang):
        self.ts.reload_translation(lang)
        return "Language changed to <highlight>{lang}<end>".format(lang=lang)

    @command(command="lang",
             params=[],
             description="Gets the language of the bot",
             access_level="all")
    def print_lang(self, _):
        return "My current language is <highlight>{lang}<end>".format(
            lang=self.ts.language)
コード例 #10
0
ファイル: lang_controller.py プロジェクト: fatpower/Tyrbot-1
class LangController:
    def inject(self, registry):
        self.ts = registry.get_instance("translation_service")
        self.bot: Tyrbot = registry.get_instance("bot")
        self.getresp = registry.get_instance(
            "translation_service").get_response

    @command(command="lang",
             params=[Options(["de_DE", "en_US"])],
             description="Changes the language of the bot",
             access_level="moderator",
             sub_command="set")
    def reload_translation(self, request, lang):
        self.ts.reload_translation(lang)
        return self.getresp("module/system", "reload_lang",
                            {"lang_code": lang})

    @command(command="lang",
             params=[],
             description="Gets the language of the bot",
             access_level="all")
    def print_lang(self, _):
        return self.getresp("module/system", "current_lang",
                            {"lang_code": self.ts.language})
コード例 #11
0
class AltsController:
    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.alts_service = registry.get_instance("alts_service")
        self.buddy_service = registry.get_instance("buddy_service")
        self.ts: TranslationService = registry.get_instance("translation_service")
        self.getresp = self.ts.get_response

    def start(self):
        self.ts.register_translation("module/alts", self.load_alts_msg)

    def load_alts_msg(self):
        with open("modules/core/alts/alts.msg", mode="r", encoding="UTF-8") as f:
            return hjson.load(f)

    @command(command="alts", params=[], access_level="all",
             description="Show your alts")
    def alts_list_cmd(self, request):
        alts = self.alts_service.get_alts(request.sender.char_id)
        blob = self.format_alt_list(alts)

        return ChatBlob(self.getresp("module/alts", "list", {"char": alts[0].name, "amount": len(alts)}), blob)

    def get_alt_status(self, status):
        if status == AltsService.MAIN:
            return " - [main]"
        else:
            return ""

    @command(command="alts", params=[Const("setmain")], access_level="all",
             description="Set a new main", extended_description="You must run this from the character you want to be your new main")
    def alts_setmain_cmd(self, request, _):
        msg, result = self.alts_service.set_as_main(request.sender.char_id)

        if result:
            return self.getresp("module/alts", "new_main", {"char":request.sender.name})
        elif msg == "not_an_alt":
            return self.getresp("module/alts", "not_an_alt")
        elif msg == "already_main":
            return self.getresp("module/alts", "already_main")
        else:
            raise Exception("Unknown msg: " + msg)

    @command(command="alts", params=[Const("add"), Character("character")], access_level="all",
             description="Add an alt")
    def alts_add_cmd(self, request, _, alt_char):
        if not alt_char.char_id:
            return self.getresp("global", "char_not_found", {"char":alt_char.name})
        elif alt_char.char_id == request.sender.char_id:
            return self.getresp("module/alts", "add_fail_self")

        msg, result = self.alts_service.add_alt(request.sender.char_id, alt_char.char_id)
        if result:
            self.bot.send_private_message(alt_char.char_id, self.getresp("module/alts", "add_success_target",
                                                                         {"char": request.sender.name}))
            return self.getresp("module/alts", "add_success_self", {"char": alt_char.name})
        elif msg == "another_main":
            return self.getresp("module/alts", "add_fail_already", {"char": alt_char.name})
        else:
            raise Exception("Unknown msg: " + msg)

    @command(command="alts", params=[Options(["rem", "remove"]), Character("character")], access_level="all",
             description="Remove an alt")
    def alts_remove_cmd(self, request, _, alt_char):
        if not alt_char.char_id:
            return self.getresp("global", "char_not_found", {"char":alt_char.name})

        msg, result = self.alts_service.remove_alt(request.sender.char_id, alt_char.char_id)
        if result:
            return self.getresp("module/alts", "rem_success", {"char": alt_char.name})
        elif msg == "not_alt":
            return self.getresp("module/alts", "rem_fail_not", {"char": alt_char.name})
        elif msg == "remove_main":
            return self.getresp("module/alts", "rem_fail_main")
        else:
            raise Exception("Unknown msg: " + msg)

    @command(command="alts", params=[Character("character")], access_level="member",
             description="Show alts of another character", sub_command="show")
    def alts_list_other_cmd(self, request, char):
        if not char.char_id:
            return self.getresp("global", "char_not_found", {"char":char.name})

        alts = self.alts_service.get_alts(char.char_id)
        blob = self.format_alt_list(alts)

        return ChatBlob(self.getresp("module/alts", "alts_list", {"char": alts[0].name, "amount": len(alts)}), blob)

    def format_alt_list(self, alts):
        blob = ""
        for alt in alts:
            blob += "<highlight>%s<end> (%d/<green>%d<end>) %s %s" % (alt.name, alt.level, alt.ai_level, alt.faction, alt.profession)
            if self.buddy_service.is_online(alt.char_id):
                blob += " [<green>Online<end>]"
            blob += "\n"
        return blob
コード例 #12
0
class LeaderController:
    NOT_LEADER_MSG = "Error! You must be raid leader, or have higher access " \
                     "level than the raid leader to use this command."

    def __init__(self):
        self.leader = None
        self.last_activity = None
        self.echo = False

    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.access_service: AccessService = registry.get_instance(
            "access_service")
        self.character_service: CharacterService = registry.get_instance(
            "character_service")
        self.bot: Tyrbot = registry.get_instance("bot")
        self.setting_service: SettingService = registry.get_instance(
            "setting_service")

    @setting(
        name="leader_echo_color",
        value="#00FF00",
        description="Color with which the leader's messages will be echoed with"
    )
    def leader_echo_color(self):
        return ColorSettingType()

    @setting(name="leader_auto_echo",
             value=True,
             description=
             "If turned on, when someone assume the leader role, leader echo "
             "will automatically be activated for said person")
    def leader_auto_echo(self):
        return BooleanSettingType()

    @command(command="leader",
             params=[],
             access_level="all",
             description="Show the current raid leader")
    def leader_show_command(self, _):
        if self.leader:
            return "The current raid leader is <highlight>%s<end>." % self.leader.name
        else:
            return "There is no current raid leader. Use <highlight><symbol>leader set<end> to become the raid leader."

    @command(
        command="leader",
        params=[Const("echo"), Options(["on", "off"])],
        access_level="all",
        description=
        "Echo whatever the current leader types in channel, in a distinctive color"
    )
    def leader_echo_command(self, request, _2, switch_to):
        if self.leader:
            if self.can_use_command(request.sender.char_id):
                self.echo = switch_to == "on"
                return "Leader echo for <highlight>%s<end> has been turned <highlight>%s<end>." % \
                       (self.leader.name, switch_to)
            else:
                return "Insufficient access level."
        elif self.leader is None and switch_to == "on":
            return "No current leader set, can't turn on leader echo."

    @command(command="leader",
             params=[Const("echo")],
             access_level="all",
             description="See the current status for leader echoing")
    def leader_echo_status_command(self, _1, _2):
        if self.leader:
            on_off = "on" if self.echo else "off"
            return "<highlight>%s<end> is set as leader, leader echo is <highlight>%s<end>" % \
                   (self.leader.name, on_off)
        return "No current leader set."

    @command(command="leader",
             params=[Const("clear")],
             access_level="all",
             description="Clear the current raid leader")
    def leader_clear_command(self, request, _):
        return self.set_raid_leader(request.sender, None)

    @command(command="leader",
             params=[Const("set")],
             access_level="all",
             description="Set (or unset) yourself as raid leader")
    def leader_set_self_command(self, request, _):
        return self.set_raid_leader(request.sender, request.sender)

    @command(command="leader",
             params=[Const("set", is_optional=True),
                     Character("character")],
             access_level="all",
             description="Set another character as raid leader")
    def leader_set_other_command(self, request, _, char):
        if not char.char_id:
            return "Could not find <highlight>%s<end>." % char.name

        return self.set_raid_leader(request.sender, char)

    @timerevent(
        budatime="1h",
        description=
        "Remove raid leader if raid leader hasn't been active for more than 1 hour"
    )
    def leader_auto_remove(self, _1, _2):
        if self.last_activity:
            if self.last_activity - int(time.time()) > 3600:
                self.leader = None
                self.last_activity = None
                self.echo = False

                self.bot.send_private_channel_message(
                    "Raid leader has been automatically "
                    "cleared because of inactivity.")
                self.bot.send_org_message(
                    "Raid leader has been automatically cleared because of inactivity."
                )

    @event(PrivateChannelService.LEFT_PRIVATE_CHANNEL_EVENT,
           "Remove raid leader if raid leader leaves private channel")
    def leader_remove_on_leave_private(self, _, event_data):
        if self.leader:
            if self.leader.char_id == event_data.char_id:
                self.leader = None
                self.last_activity = None
                self.echo = False
                self.bot.send_private_channel_message(
                    "%s left private channel, and has been cleared as raid leader."
                    % self.character_service.resolve_char_to_name(
                        event_data.char_id))

    @event(OrgMemberController.ORG_MEMBER_LOGOFF_EVENT,
           "Remove raid leader if raid leader logs off")
    def leader_remove_on_logoff(self, _, event_data):
        if self.leader:
            if self.leader.char_id == event_data.char_id:
                self.leader = None
                self.last_activity = None
                self.echo = False
                self.bot.send_org_message(
                    "%s has logged off, and has been cleared as raid leader." %
                    self.character_service.resolve_char_to_name(
                        event_data.char_id))

    @event(PrivateChannelService.PRIVATE_CHANNEL_MESSAGE_EVENT,
           "Echo leader messages from private channel",
           is_hidden=True)
    def leader_echo_private_event(self, _, event_data):
        if self.leader and self.echo:
            if self.leader.char_id == event_data.char_id:
                if self.setting_service.get(
                        "symbol").get_value() != event_data.message[0]:
                    self.leader_echo(event_data.char_id, event_data.message,
                                     "priv")

    @event(PublicChannelService.ORG_CHANNEL_MESSAGE_EVENT,
           "Echo leader messages from org channel",
           is_hidden=True)
    def leader_echo_org_event(self, _, event_data):
        if self.leader and self.echo:
            if self.leader.char_id == event_data.char_id:
                if self.setting_service.get(
                        "symbol").get_value() != event_data.message[0]:
                    self.leader_echo(event_data.char_id, event_data.message,
                                     "org")

    def leader_echo(self, char_id, message, channel):
        sender = self.character_service.resolve_char_to_name(char_id)
        color = self.setting_service.get("leader_echo_color").get_value()

        if channel == "org":
            self.bot.send_org_message("%s: <font color=%s>%s" %
                                      (sender, color, message))
        if channel == "priv":
            self.bot.send_private_channel_message("%s: <font color=%s>%s" %
                                                  (sender, color, message))

        self.activity_done()

    def activity_done(self):
        self.last_activity = int(time.time())

    def can_use_command(self, char_id):
        if not self.leader or self.access_service.has_sufficient_access_level(
                char_id, self.leader.char_id):
            self.activity_done()
            return True

        return False

    def set_raid_leader(self, sender, set_to):
        if set_to is None:
            if not self.leader:
                return "There is no current raid leader."
            elif self.leader.char_id == sender.char_id:
                self.leader = None
                self.echo = False
                return "You have been removed as raid leader."
            elif self.can_use_command(sender.char_id):
                old_leader = self.leader
                self.leader = None
                self.echo = False
                self.bot.send_private_message(
                    old_leader.char_id,
                    "You have been removed as raid leader by <highlight>%s<end>."
                    % sender.name)
                return "You have removed <highlight>%s<end> as raid leader." % old_leader.name
            else:
                return "You do not have a high enough access level to remove raid leader from <highlight>%s<end>." % \
                       self.leader.name
        elif sender.char_id == set_to.char_id:
            if not self.leader:
                self.leader = sender
                self.echo = self.setting_service.get(
                    "leader_auto_echo").get_value()
                reply = "You have been set as raid leader."
                if self.echo:
                    reply += " Leader echo is <green>enabled<end>."
                return reply
            elif self.leader.char_id == sender.char_id:
                self.leader = None
                self.echo = False
                return "You have been removed as raid leader."
            elif self.can_use_command(sender.char_id):
                old_leader = self.leader
                self.leader = sender
                self.echo = self.setting_service.get(
                    "leader_auto_echo").get_value()
                reply = "<highlight>%s<end> has taken raid leader from you." % sender.name
                if self.echo:
                    reply += " Leader echo is <green>enabled<end>."
                self.bot.send_private_message(old_leader.char_id, reply)
                reply = "You have taken raid leader from <highlight>%s<end>." % old_leader.name
                if self.echo:
                    reply += " Leader echo is <green>enabled<end>."
                return reply
            else:
                return "You do not have a high enough access level to take raid leader from <highlight>%s<end>." % \
                       self.leader.name
        else:
            if self.can_use_command(sender.char_id):
                self.leader = set_to
                self.echo = self.setting_service.get(
                    "leader_auto_echo").get_value()
                reply = "<highlight>%s<end> has set you as raid leader." % sender.name
                if self.echo:
                    reply += " Leader echo is <green>enabled<end>."
                self.bot.send_private_message(set_to.char_id, reply)
                reply = "<highlight>%s<end> has been set as raid leader by %s." % (
                    set_to.name, sender.name)
                if self.echo:
                    reply += " Leader echo is <green>enabled<end>."
                return reply
            else:
                return "You do not have a high enough access level to take raid leader from <highlight>%s<end>." % \
                       self.leader.name
コード例 #13
0
class WhatBuffsController:
    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")

    def pre_start(self):
        self.db.load_sql_file(self.module_dir + "/sql/" + "item_buffs.sql")
        self.db.load_sql_file(self.module_dir + "/sql/" + "item_types.sql")
        self.db.load_sql_file(self.module_dir + "/sql/" + "skills.sql")

    def start(self):
        self.command_alias_service.add_alias("buffs", "whatbuffs")

    @command(command="whatbuffs",
             params=[],
             access_level="all",
             description="Find items or nanos that buff a skill (or ability)")
    def whatbuffs_list_cmd(self, request):
        data = self.db.query("SELECT name FROM skills ORDER BY name ASC")
        blob = ""
        for row in data:
            blob += self.text.make_tellcmd(row.name,
                                           "whatbuffs %s" % row.name) + "\n"

        blob += self.get_footer()
        return ChatBlob("Whatbuffs Skill List", blob)

    @command(
        command="whatbuffs",
        params=[
            Any("skill"),
            Options([
                "arms", "back", "chest", "deck", "feet", "fingers", "hands",
                "head", "hud", "legs", "nanoprogram", "neck", "shoulders",
                "unknown", "util", "weapon", "wrists", "all"
            ])
        ],
        access_level="all",
        description=
        "Find items or nanos that buff a skill (or ability) for a particular item type"
    )
    def whatbuffs_detail_cmd(self, request, skill_name, item_type):
        item_type = item_type.capitalize()

        return self.show_search_results(item_type, skill_name)

    @command(command="whatbuffs",
             params=[Any("skill")],
             access_level="all",
             description="Find items or nanos that buff a skill (or ability)")
    def whatbuffs_skill_cmd(self, request, skill_name):
        skills = self.search_for_skill(skill_name)
        if len(skills) == 0:
            return "Could not find skill <highlight>%s</highlight>." % skill_name
        elif len(skills) == 1:
            skill = skills.pop()

            data = self.db.query(
                "SELECT i.item_type, COUNT(1) AS cnt "
                "FROM aodb "
                "JOIN item_types i ON aodb.highid = i.item_id "
                "JOIN item_buffs b ON aodb.highid = b.item_id "
                "JOIN skills s ON b.attribute_id = s.id "
                "WHERE s.id = ? "
                "GROUP BY item_type "
                "HAVING cnt > 0 "
                "ORDER BY item_type ASC", [skill.id])

            blob = ""
            total_count = 0
            for row in data:
                blob += "%s (%d)\n" % (self.text.make_tellcmd(
                    row.item_type, "whatbuffs %s %s" %
                    (skill.name, row.item_type)), row.cnt)
                total_count += row.cnt
            blob += "\n%s (%d)\n" % (self.text.make_tellcmd(
                "All", "whatbuffs %s %s" % (skill.name, "All")), total_count)

            blob += self.get_footer()
            return ChatBlob("Whatbuffs %s - Choose Type" % skill.name, blob)
        else:
            blob = "Choose a skill:\n\n"
            for skill in skills:
                blob += self.text.make_tellcmd(
                    skill.name, "whatbuffs %s" % skill.name) + "\n"

            blob += self.get_footer()
            return ChatBlob("Whatbuffs - Choose Skill", blob)

    def search_for_skill(self, skill_name):
        skill_name = skill_name.lower()

        data = self.db.query(
            "SELECT id, name FROM skills WHERE name <EXTENDED_LIKE=0> ? OR common_name <EXTENDED_LIKE=1> ?",
            [skill_name, skill_name],
            extended_like=True)

        # check for exact match first, in order to disambiguate between Bow and Bot Special Attack
        for row in data:
            if row.name.lower() == skill_name:
                return [row]

        return data

    def show_search_results(self, item_type, skill_name):
        skills = self.search_for_skill(skill_name)

        if len(skills) == 0:
            return "Could not find skill <highlight>%s</highlight>." % skill_name
        elif len(skills) == 1:
            skill = skills.pop()
            return self.get_search_results(item_type, skill)
        else:
            blob = ""
            for skill in skills:
                blob += self.text.make_tellcmd(
                    skill.name, "whatbuffs %s %s" %
                    (skill.name, item_type)) + "\n"

            return ChatBlob("Whatbuffs - Choose Skill", blob)

    def get_search_results(self, item_type, skill):
        data = self.db.query(
            "SELECT aodb.*, b.amount, i.item_type "
            "FROM aodb "
            "JOIN item_types i ON aodb.highid = i.item_id "
            "JOIN item_buffs b ON aodb.highid = b.item_id "
            "JOIN skills s ON b.attribute_id = s.id "
            "WHERE i.item_type LIKE ? AND s.id = ? "
            "ORDER BY item_type, amount DESC",
            ["%" if item_type == "All" else item_type, skill.id])

        if len(data) == 0:
            return "No items found of type <highlight>%s</highlight> that buff <highlight>%s</highlight>." % (
                item_type, skill.name)
        else:
            current_item_type = ""
            blob = ""
            for row in data:
                if current_item_type != row.item_type:
                    blob += "\n\n<header2>%s</header2>\n" % row.item_type
                    current_item_type = row.item_type

                blob += "%s (%d)\n" % (self.text.make_item(
                    row.lowid, row.highid, row.highql, row.name), row.amount)

            blob += self.get_footer()

            return ChatBlob(
                "Whatbuffs - %s %s (%d)" % (skill.name, item_type, len(data)),
                blob)

    def get_footer(self):
        return "\nItem DB Extraction Info provided by Unk"
コード例 #14
0
ファイル: member_controller.py プロジェクト: wowpin/Tyrbot
class MemberController:
    MEMBER_BUDDY_TYPE = "member"

    MEMBER_LOGON_EVENT = "member_logon_event"
    MEMBER_LOGOFF_EVENT = "member_logoff_event"

    def inject(self, registry):
        self.db = registry.get_instance("db")
        self.private_channel_service = registry.get_instance("private_channel_service")
        self.buddy_service = registry.get_instance("buddy_service")
        self.bot = registry.get_instance("bot")
        self.access_service = registry.get_instance("access_service")
        self.command_alias_service = registry.get_instance("command_alias_service")
        self.event_service = registry.get_instance("event_service")

    def pre_start(self):
        self.access_service.register_access_level("member", 90, self.check_member)
        self.event_service.register_event_type(self.MEMBER_LOGON_EVENT)
        self.event_service.register_event_type(self.MEMBER_LOGOFF_EVENT)
        self.bot.add_packet_handler(BuddyAdded.id, self.handle_member_logon)

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS members (char_id INT NOT NULL PRIMARY KEY, auto_invite INT DEFAULT 0);")
        self.command_alias_service.add_alias("adduser", "member add")
        self.command_alias_service.add_alias("remuser", "member rem")
        self.command_alias_service.add_alias("members", "member")

    @event(event_type="connect", description="Add members as buddies of the bot on startup")
    def handle_connect_event(self, event_type, event_data):
        for row in self.get_all_members():
            if row.auto_invite == 1:
                self.buddy_service.add_buddy(row.char_id, self.MEMBER_BUDDY_TYPE)

    @command(command="member", params=[Const("add"), Character("character")], access_level=OrgMemberController.ORG_ACCESS_LEVEL,
             description="Add a member")
    def member_add_cmd(self, request, _, char):
        if char.char_id:
            if self.get_member(char.char_id):
                return "<highlight>%s<end> is already a member." % char.name
            else:
                self.add_member(char.char_id)
                return "<highlight>%s<end> has been added as a member." % char.name
        else:
            return "Could not find character <highlight>%s<end>." % char.name

    @command(command="member", params=[Options(["rem", "remove"]), Character("character")], access_level=OrgMemberController.ORG_ACCESS_LEVEL,
             description="Remove a member")
    def member_remove_cmd(self, request, _, char):
        if char.char_id:
            if self.get_member(char.char_id):
                self.remove_member(char.char_id)
                return "<highlight>%s<end> has been removed as a member." % char.name
            else:
                return "<highlight>%s<end> is not a member." % char.name
        else:
            return "Could not find character <highlight>%s<end>." % char.name

    @command(command="member", params=[Const("list", is_optional=True)], access_level=OrgMemberController.ORG_ACCESS_LEVEL,
             description="List members")
    def member_list_cmd(self, request, _):
        data = self.get_all_members()
        count = len(data)
        blob = ""
        for row in data:
            blob += str(row.name) + "\n"
        return ChatBlob("Members (%d)" % count, blob)

    @command(command="autoinvite", params=[Options(["on", "off"])], access_level="all",
             description="Set your auto invite preference")
    def autoinvite_cmd(self, request, pref):
        pref = pref.lower()
        member = self.get_member(request.sender.char_id)
        if member:
            self.update_auto_invite(request.sender.char_id, 1 if pref == "on" else 0)
            return "Your auto invite preference has been set to <highlight>%s<end>." % pref
        else:
            return "You must be a member of this bot to set your auto invite preference."

    @event(event_type=MEMBER_LOGON_EVENT, description="Auto invite members to the private channel when they logon")
    def handle_buddy_logon(self, event_type, event_data):
        if event_data.auto_invite == 1:
            self.bot.send_private_message(event_data.char_id, "You have been auto-invited to the private channel.")
            self.private_channel_service.invite(event_data.char_id)

    @event(event_type=BanService.BAN_ADDED_EVENT, description="Remove characters as members when they are banned")
    def ban_added_event(self, event_type, event_data):
        self.remove_member(event_data.char_id)

    def handle_member_logon(self, packet: BuddyAdded):
        member = self.get_member(packet.char_id)
        if member:
            if packet.online:
                self.event_service.fire_event(self.MEMBER_LOGON_EVENT, member)
            else:
                self.event_service.fire_event(self.MEMBER_LOGOFF_EVENT, member)

    def add_member(self, char_id, auto_invite=1):
        self.buddy_service.add_buddy(char_id, self.MEMBER_BUDDY_TYPE)
        if not self.get_member(char_id):
            self.db.exec("INSERT INTO members (char_id, auto_invite) VALUES (?, ?)", [char_id, auto_invite])

    def remove_member(self, char_id):
        self.buddy_service.remove_buddy(char_id, self.MEMBER_BUDDY_TYPE)
        self.db.exec("DELETE FROM members WHERE char_id = ?", [char_id])

    def update_auto_invite(self, char_id, auto_invite):
        self.db.exec("UPDATE members SET auto_invite = ? WHERE char_id = ?", [auto_invite, char_id])

    def get_member(self, char_id):
        return self.db.query_single("SELECT char_id, auto_invite FROM members WHERE char_id = ?", [char_id])

    def get_all_members(self):
        return self.db.query("SELECT COALESCE(p.name, m.char_id) AS name, m.char_id, m.auto_invite FROM members m LEFT JOIN player p ON m.char_id = p.char_id ORDER BY p.name ASC")

    def check_member(self, char_id):
        return self.get_member(char_id) is not None
コード例 #15
0
ファイル: topic_controller.py プロジェクト: Budabot/Tyrbot
class TopicController:
    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util = registry.get_instance("util")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.private_channel_service: PrivateChannelService = registry.get_instance(
            "private_channel_service")
        self.setting_service = registry.get_instance("setting_service")

    def start(self):
        self.command_alias_service.add_alias("motd", "topic")
        self.command_alias_service.add_alias("orders", "topic")

        self.setting_service.register(self.module_name, "topic", "",
                                      DictionarySettingType(), "The bot topic")

    @command(command="topic",
             params=[],
             access_level="guest",
             description="Show the current topic")
    def topic_show_command(self, request):
        topic = self.get_topic()
        if topic:
            return self.format_topic_message(topic)
        else:
            return "There is no current topic."

    @command(command="topic",
             params=[Options(["clear", "unset"])],
             access_level="guest",
             description="Clears the current topic")
    def topic_clear_command(self, request, _):
        # TODO compare against access level of existing topic author
        self.clear_topic()

        return "The topic has been cleared."

    @command(command="topic",
             params=[Const("set", is_optional=True),
                     Any("topic_message")],
             access_level="guest",
             description="Set the current topic")
    def topic_set_command(self, request, _, topic_message):
        # TODO compare against access level of existing topic author
        self.set_topic(topic_message, request.sender)

        return "The topic has been set."

    def format_topic_message(self, topic):
        time_string = self.util.time_to_readable(
            int(time.time()) - topic["created_at"])
        return "Topic: <highlight>%s</highlight> [set by <highlight>%s</highlight>][%s ago]" % (
            topic["topic_message"], topic["created_by"]["name"], time_string)

    def get_topic(self):
        return self.setting_service.get("topic").get_value()

    def clear_topic(self):
        self.setting_service.get("topic").set_value("")

    def set_topic(self, message, sender):
        topic = {
            "topic_message": message,
            "created_by": {
                "char_id": sender.char_id,
                "name": sender.name
            },
            "created_at": int(time.time())
        }

        self.setting_service.get("topic").set_value(topic)

    @event(PrivateChannelService.JOINED_PRIVATE_CHANNEL_EVENT,
           "Show topic to characters joining the private channel")
    def char_join_event(self, _, event_data):
        topic = self.get_topic()
        if topic:
            self.bot.send_private_message(event_data.char_id,
                                          self.format_topic_message(topic),
                                          conn=event_data.conn)

    @event(PrivateChannelService.LEFT_PRIVATE_CHANNEL_EVENT,
           "Clear topic when there are no characters in the private channel")
    def char_leave_event(self, _, event_data):
        if self.get_topic() and len(event_data.conn.private_channel) == 0:
            self.clear_topic()
コード例 #16
0
ファイル: auction_controller.py プロジェクト: sawtyss/Tyrbot
class AuctionController:
    def __init__(self):
        self.auction: AuctionStrategy = None

    @setting(name="auction_length",
             value="90s",
             description="Regular auction length in seconds")
    def auction_length(self):
        return TimeSettingType()

    @setting(name="auction_announce_interval",
             value="15s",
             description="Auction announce interval")
    def auction_announce_interval(self):
        return TimeSettingType()

    @setting(name="auction_late_bid_extension",
             value="10s",
             description="How much to extend auction in case of late bid")
    def auction_late_bid_extension(self):
        return TimeSettingType()

    @setting(name="auction_late_bid_threshold",
             value="10s",
             description="Threshold for a bid to be considered late")
    def auction_late_bid_threshold(self):
        return TimeSettingType()

    @command(command="auction",
             params=[],
             description="Show auction status",
             access_level="member")
    def auction_cmd(self, request):
        if not self.is_auction_running():
            return "No auction running."

        return self.auction.get_auction_list()

    @command(command="auction",
             params=[Const("start"), Any("items")],
             description="Start an auction, with one or more items",
             access_level="moderator",
             sub_command="modify")
    def auction_start_cmd(self, request, _, items):
        if self.is_auction_running():
            return "Auction already running."

        items = re.findall(
            r"(([^<]+)?<a href=[\"\']itemref://(\d+)/(\d+)/(\d+)[\"\']>([^<]+)</a>([^<]+)?)",
            items)
        # TODO choose auction strategy impl
        self.auction = AuctionStrategy()
        for item in items:
            self.auction.add_item(item[0])

        auction_length = self.auction_length().get_value()
        announce_interval = self.auction_announce_interval().get_value()
        late_bid_threshold = self.auction_late_bid_threshold().get_value()
        late_bid_extension = self.auction_late_bid_extension().get_value()

        return self.auction.start(request.sender, auction_length,
                                  announce_interval, late_bid_threshold,
                                  late_bid_extension)

    @command(command="auction",
             params=[Options(["cancel", "end"])],
             description="Cancel ongoing auction",
             access_level="moderator",
             sub_command="modify")
    def auction_cancel_cmd(self, request, _):
        if not self.is_auction_running():
            return "No auction running."

        result = self.auction.cancel(request.sender)
        self.auction = None
        return result

    @command(command="auction",
             params=[
                 Const("bid"),
                 Int("amount", is_optional=True),
                 Const("all", is_optional=True),
                 Int("item_index", is_optional=True)
             ],
             description="Bid on an item",
             access_level="member")
    def auction_bid_cmd(self, request, _, amount, all_amount, item_index):
        if not self.is_auction_running():
            return "No auction running."

        return self.auction.add_bid(request.sender, all_amount or amount,
                                    item_index)

    def is_auction_running(self):
        return self.auction and self.auction.is_running
コード例 #17
0
class CloakController:
    MESSAGE_SOURCE = "cloak_reminder"
    CLOAK_EVENT = "cloak"

    CLOAK_STATUS_OFF = "off"
    CLOAK_STATUS_ON = "on"
    CLOAK_STATUS_MANUAL = "on*"

    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.db = registry.get_instance("db")
        self.util = registry.get_instance("util")
        self.text = registry.get_instance("text")
        self.character_service = registry.get_instance("character_service")
        self.command_alias_service = registry.get_instance("command_alias_service")
        self.timer_controller = registry.get_instance("timer_controller", is_optional=True)
        self.event_service = registry.get_instance("event_service")
        self.access_service = registry.get_instance("access_service")
        self.message_hub_service = registry.get_instance("message_hub_service")

    def pre_start(self):
        self.bot.register_packet_handler(PublicChannelMessage.id, self.handle_public_message)
        self.event_service.register_event_type(self.CLOAK_EVENT)
        self.message_hub_service.register_message_source(self.MESSAGE_SOURCE)

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS cloak_status (char_id INT NOT NULL, action VARCHAR(10) NOT NULL, created_at INT NOT NULL, org_id INT NOT NULL)")
        self.command_alias_service.add_alias("city", "cloak")

    @command(command="cloak", params=[Const("history"), Int("org_id")], access_level="org_member",
             description="Shows the cloak history")
    def cloak_history_command(self, request, _, org_id):
        data = self.db.query("SELECT c.*, p.name FROM cloak_status c LEFT JOIN player p ON c.char_id = p.char_id "
                             "WHERE c.org_id = ? ORDER BY created_at DESC LIMIT 20", [org_id])

        blob = ""
        for row in data:
            action = self.get_cloak_status_display(row.action)
            blob += "%s turned the device %s at %s.\n" % (row.name, action, self.util.format_datetime(row.created_at))

        conn = self.bot.get_conn_by_org_id(org_id)
        org_name = conn.get_org_name()
        return ChatBlob(f"Cloak History for {org_name}", blob)

    @command(command="cloak", params=[NamedFlagParameters(["all"])], access_level="org_member",
             description="Shows the cloak status")
    def cloak_command(self, request, flag_params):
        t = int(time.time())

        if flag_params.all:
            blob = ""
            for _id, conn in self.bot.get_conns(lambda x: x.is_main and x.org_id):
                row = self.db.query_single("SELECT c.char_id, c.action, c.created_at, p.name FROM cloak_status c LEFT JOIN player p ON c.char_id = p.char_id "
                                           "WHERE c.org_id = ? ORDER BY created_at DESC LIMIT 1", [conn.org_id])

                org_name = conn.get_org_name()
                if row:
                    action = self.get_cloak_status_display(row.action)
                    time_str = self.util.time_to_readable(t - row.created_at)
                    history_link = self.text.make_tellcmd("History", f"cloak history {conn.org_id}")
                    blob += f"{org_name} - {action} [{time_str} ago] {history_link}\n"
                else:
                    blob += f"{org_name} - Unknown\n"

            title = "Cloak Status"

            return ChatBlob(title, blob)
        else:
            conn = request.conn
            if not conn.org_id:
                return "This bot is not a member of an org."

            row = self.db.query_single("SELECT c.char_id, c.action, c.created_at, p.name FROM cloak_status c LEFT JOIN player p ON c.char_id = p.char_id "
                                       "WHERE c.org_id = ? ORDER BY created_at DESC LIMIT 1", [conn.org_id])

            org_name = conn.get_org_name()
            if row:
                action = self.get_cloak_status_display(row.action)
                time_str = self.util.time_to_readable(t - row.created_at)
                return f"{org_name} - {action} [{time_str} ago]"
            else:
                return f"{org_name} - Unknown cloak status"

    @command(command="cloak", params=[Options(["raise", "on"]), Int("org_id", is_optional=True)], access_level="org_member",
             description="Manually raises the cloak status on the bot")
    def cloak_raise_command(self, request, _, org_id):
        org_id = org_id or request.conn.org_id

        if not org_id:
            return "This bot is not a member of an org."

        row = self.db.query_single("SELECT action FROM cloak_status WHERE org_id = ?", [org_id])
        if row and (row.action == self.CLOAK_STATUS_ON or row.action == self.CLOAK_STATUS_MANUAL):
            return "The cloaking device is already <green>enabled</green>."

        self.db.exec("INSERT INTO cloak_status (char_id, action, created_at, org_id) VALUES (?, ?, ?, ?)",
                     [request.sender.char_id, self.CLOAK_STATUS_MANUAL, int(time.time()), org_id])
        return "The cloaking device has been set to enabled in the bot (you must still enable the cloak if it is disabled)."

    @event(event_type=CLOAK_EVENT, description="Record when the city cloak is turned off and on", is_system=True)
    def city_cloak_event(self, event_type, event_data):
        self.db.exec("INSERT INTO cloak_status (char_id, action, created_at, org_id) VALUES (?, ?, ?, ?)",
                     [event_data.char_id, event_data.action, int(time.time()), event_data.conn.org_id])

    @timerevent(budatime="15m", description="Reminds the players when cloak can be raised")
    def cloak_reminder_event(self, event_type, event_data):
        messages = []
        for _id, conn in self.bot.get_conns(lambda x: x.is_main and x.org_id):
            row = self.db.query_single("SELECT c.*, p.name FROM cloak_status c LEFT JOIN player p ON c.char_id = p.char_id "
                                       "WHERE c.org_id = ? ORDER BY created_at DESC LIMIT 1", [conn.org_id])
            if row:
                one_hour = 3600
                t = int(time.time())
                time_until_change = row.created_at + one_hour - t
                if row.action == self.CLOAK_STATUS_OFF and 0 >= time_until_change > (one_hour * 6 * -1):
                    time_str = self.util.time_to_readable(t - row.created_at)
                    org_name = conn.get_org_name()
                    messages.append(f"The cloaking device for org <highlight>{org_name}</highlight> is <orange>disabled</orange> but can be enabled. "
                                    f"<highlight>{row.name}</highlight> disabled it {time_str} ago.")

        if messages:
            self.message_hub_service.send_message(self.MESSAGE_SOURCE, None, None, "\n".join(messages))

    @event(event_type=CLOAK_EVENT, description="Set a timer for when cloak can be raised and lowered")
    def city_cloak_timer_event(self, event_type, event_data):
        if event_data.action == self.CLOAK_STATUS_OFF:
            timer_name = f"Raise City Cloak ({event_data.conn.get_org_name()})"
        elif event_data.action == self.CLOAK_STATUS_ON:
            timer_name = f"Lower City Cloak ({event_data.conn.get_org_name()})"
        else:
            raise Exception(f"Unknown cloak action '{event_data.action}'")

        timer_name = self.timer_controller.get_timer_name(timer_name)

        self.timer_controller.add_timer(timer_name, event_data.char_id, PublicChannelService.ORG_CHANNEL_COMMAND, int(time.time()), 3600)

    def handle_public_message(self, conn: Conn, packet: PublicChannelMessage):
        if not conn.is_main:
            return

        ext_msg = packet.extended_message
        if ext_msg and ext_msg.category_id == 1001 and ext_msg.instance_id == 1:
            char_name = ext_msg.params[0]
            char_id = self.character_service.resolve_char_to_id(char_name)
            action = ext_msg.params[1]
            self.event_service.fire_event(self.CLOAK_EVENT, DictObject({"char_id": char_id, "name": char_name, "action": action, "conn": conn}))

    def get_cloak_status_display(self, status):
        if status == self.CLOAK_STATUS_ON:
            return "<green>on</green>"
        elif status == self.CLOAK_STATUS_MANUAL:
            return "<green>on*</green>"
        elif status == self.CLOAK_STATUS_OFF:
            return "<orange>off</orange>"
        else:
            return "<highlight>Unknown</highlight>"
コード例 #18
0
class PointsController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.character_service: CharacterService = registry.get_instance("character_service")
        self.util: Util = registry.get_instance("util")
        self.setting_service: SettingService = registry.get_instance("setting_service")
        self.alts_service: AltsService = registry.get_instance("alts_service")

    def start(self):
        self.db.exec("CREATE TABLE IF NOT EXISTS points (char_id BIGINT PRIMARY KEY, points INT DEFAULT 0, created_at INT NOT NULL, "
                     "disabled SMALLINT DEFAULT 0)")
        self.db.exec("CREATE TABLE IF NOT EXISTS points_log (log_id INT PRIMARY KEY, char_id BIGINT NOT NULL, audit INT NOT NULL, "
                     "leader_id BIGINT NOT NULL, reason VARCHAR(255), created_at INT NOT NULL)")
        self.db.exec("CREATE TABLE IF NOT EXISTS points_presets (preset_id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, "
                     "points INT DEFAULT 1, UNIQUE(name))")

        if self.db.query_single("SELECT COUNT(*) AS count FROM points_presets").count < 1:
            # Populate with pre-made presets if empty
            presets = ["s13", "s28", "s35", "s42", "zodiac", "zod",
                       "tnh", "beast", "12m", "tara", "pvp", "towers",
                       "wipe", "clanwipe", "clan", "omniwipe", "omni",
                       "bonus", "early"]
            sql = "INSERT INTO points_presets (name) VALUES (?)"
            for preset in presets:
                self.db.exec(sql, [preset])

    @command(command="account", params=[Const("create"), Character("char")], access_level="moderator",
             description="Create a new account for given character name", sub_command="modify")
    def bank_create_cmd(self, request, _, char: SenderObj):
        alts_info = self.alts_service.get_alts(char.char_id)

        for alt in alts_info:
            sql = "SELECT char_id, disabled FROM points WHERE char_id = ? LIMIT 1"
            row = self.db.query_single(sql, [alt.char_id])

            if row:
                was_disabled = False

                if row.disabled == 1:
                    if self.db.exec("UPDATE points SET disabled = 0 WHERE char_id = ?", [alt.char_id]):
                        was_disabled = True

                if alt.char_id == char.char_id:
                    if was_disabled:
                        self.add_log_entry(alt.char_id, request.sender.char_id, "Account was re-enabled by %s" % request.sender.name)
                        return "<highlight>%s</highlight>'s account has been re-enabled." % char.name
                    else:
                        return "<highlight>%s</highlight> already has an account." % char.name
                else:
                    if was_disabled:
                        self.add_log_entry(alt.char_id, request.sender.char_id, "Account was re-enabled by %s" % request.sender.name)
                        return "<highlight>%s</highlight>'s (%s) account has been re-enabled." % (char.name, alt.name)
                    else:
                        return "<highlight>%s</highlight> (%s) already has an account." % (char.name, alt.name)

        main_info = alts_info[0]
        changed_to_main = main_info.char_id == char.char_id

        self.create_account(main_info.char_id, request.sender)

        name_reference = "%s (%s)" % (char.name, main_info.name) if changed_to_main else char.name
        return "A new account has been created for <highlight>%s</highlight>." % name_reference

    @command(command="account", params=[Const("close"), Character("char")], access_level="moderator",
             description="Close the account for given character name", sub_command="modify")
    def close_account_cmd(self, request, _, char: SenderObj):
        main = self.alts_service.get_main(char.char_id)

        sql = "UPDATE points SET disabled = 1 WHERE char_id = ?"
        if self.db.exec(sql, [main.char_id]) > 0:
            reason = f"Account was closed by {request.sender.name}"
            self.add_log_entry(main.char_id, request.sender.char_id, reason)
            name_reference = "%s (%s)" % (char.name, main.name) if main.char_id != char.char_id else char.name
            return f"<highlight>{name_reference}</highlight> has had their account disabled. Logs have been preserved."
        else:
            return "<highlight>%s</highlight> does not have an open account." % char.name

    @command(command="account", params=[Const("history"), Int("log_id")], access_level="moderator",
             description="Look up specific account history record", sub_command="modify")
    def account_history_cmd(self, request, _, log_id: int):
        log_entry = self.db.query_single("SELECT log_id, char_id, audit, leader_id, reason, created_at FROM points_log WHERE log_id = ?", [log_id])

        if not log_entry:
            return "No account history record with given ID <highlight>%d</highlight>." % log_id

        char_name = self.character_service.resolve_char_to_name(log_entry.char_id)
        leader_name = self.character_service.resolve_char_to_name(log_entry.leader_id)

        blob = f"ID: <highlight>{log_entry.log_id}</highlight>\n"
        blob += f"Account: <highlight>{char_name}</highlight>\n"
        blob += f"Action by: <highlight>{leader_name}</highlight>\n"
        blob += "Type: <highlight>%s</highlight>\n" % ("Management" if log_entry.audit == 0 else "Altering of points")
        blob += f"Reason: <highlight>{log_entry.reason}</highlight>\n"
        blob += f"Audit: <highlight>{log_entry.audit}</highlight>\n"
        action_links = None
        if log_entry.audit == 0:
            if "closed" in log_entry.reason:
                action_links = self.text.make_tellcmd("Open the account", "account create %s" % char_name)
            elif "re-enabled" in log_entry.reason:
                action_links = self.text.make_tellcmd("Close the account", "account close %s" % char_name)
        else:
            reason = f"Points from event ({log_id}) have been retracted"
            if log_entry.audit < 0:
                action_links = self.text.make_tellcmd("Retract", f"account add {char_name} {-log_entry.audit} {reason}")
            else:
                action_links = self.text.make_tellcmd("Retract", f"account rem {char_name} {log_entry.audit} {reason}")

        blob += "Actions available: [%s]\n" % (action_links if action_links is not None else "No actions available")

        return ChatBlob(f"Account History Record ({log_id})", blob)

    @command(command="account", params=[Const("add"), Character("char"), Int("amount"), Any("reason")], access_level="moderator",
             description="Add points to an account", sub_command="modify")
    def account_add_cmd(self, request, _, char: SenderObj, amount: int, reason: str):
        main = self.alts_service.get_main(char.char_id)
        row = self.get_account(main.char_id, request.conn)

        if not row:
            return f"<highlight>{char.name}</highlight> does not have an account."

        if row.disabled == 1:
            return f"Account for <highlight>{char.name}</highlight> is disabled and cannot be altered."

        self.alter_points(main.char_id, request.sender.char_id, reason, amount)

        return f"<highlight>{char.name}</highlight> has had <highlight>{amount}</highlight> points added to their account."

    @command(command="account", params=[Options(["rem", "remove"]), Character("char"), Int("amount"), Any("reason")], access_level="moderator",
             description="Remove points from an account", sub_command="modify")
    def account_remove_cmd(self, request, _, char: SenderObj, amount: int, reason: str):
        main = self.alts_service.get_main(char.char_id)
        row = self.get_account(main.char_id, request.conn)

        if not row:
            return f"<highlight>{char.name}</highlight> does not have an account."

        if row.disabled == 1:
            return f"Account for <highlight>{char.name}</highlight> is disabled and cannot be altered."

        if amount > row.points:
            return f"<highlight>{char.name}</highlight> only has <highlight>{row.points}</highlight> points."

        self.alter_points(main.char_id, request.sender.char_id, reason, -amount)

        return f"<highlight>{char.name}</highlight> has had <highlight>{amount}</highlight> points removed from their account."

    @command(command="account", params=[NamedParameters(["page"])], access_level="all",
             description="Look up your account")
    def account_self_cmd(self, request, named_params):
        return self.get_account_display(request.sender, named_params.page)

    @command(command="account", params=[Character("char"), NamedParameters(["page"])], access_level="moderator",
             description="Look up account of another char", sub_command="modify")
    def account_other_cmd(self, request, char: SenderObj, named_params):
        return self.get_account_display(char, named_params.page)

    @command(command="raid", params=[Const("presets"), Const("add"), Any("name"), Int("points")], access_level="admin",
             description="Add new points preset", sub_command="manage_points")
    def presets_add_cmd(self, request, _1, _2, name: str, points: int):
        count = self.db.query_single("SELECT COUNT(*) AS count FROM points_presets WHERE name = ?", [name]).count

        if count > 0:
            return "A preset already exists with the name <highlight>%s</highlight>." % name

        sql = "INSERT INTO points_presets (name, points) VALUES (?,?)"
        self.db.exec(sql, [name, points])
        return "A preset with the name <highlight>%s</highlight> was added, worth <green>%d</green> points." % (name, points)

    @command(command="raid", params=[Const("presets"), Const("rem"), Int("preset_id")], access_level="admin",
             description="Delete preset", sub_command="manage_points")
    def presets_rem_cmd(self, request, _1, _2, preset_id: int):
        if self.db.exec("DELETE FROM points_presets WHERE preset_id = ?", [preset_id]) > 0:
            return "Successfully removed preset with ID <highlight>%d</highlight>." % preset_id
        else:
            return "No preset with given ID <highlight>%d</highlight>." % preset_id

    @command(command="raid", params=[Const("presets"), Const("alter"), Int("preset_id"), Int("new_points")], access_level="admin",
             description="Alter the points dished out by given preset", sub_command="manage_points")
    def presets_alter_cmd(self, request, _1, _2, preset_id: int, new_points: int):
        preset = self.db.query_single("SELECT * FROM points_presets WHERE preset_id = ?", [preset_id])

        if not preset:
            return f"Preset with ID <highlight>{preset_id}</highlight> does not exist."

        self.db.exec("UPDATE points_presets SET points = ? WHERE preset_id = ?", [new_points, preset_id])
        return "Successfully updated the preset, <highlight>%s</highlight>, to dish out " \
               "<green>%d</green> points instead of <red>%d</red>." % (preset.name, new_points, preset.points)

    @command(command="raid", params=[Options(["presets", "addpts"])], access_level="member",
             description="See list of points presets")
    def presets_cmd(self, request, _):
        return ChatBlob("Raid Points Presets", self.build_preset_list())

    def build_preset_list(self):
        presets = self.db.query("SELECT * FROM points_presets ORDER BY name ASC, points DESC")

        if presets:
            blob = ""

            for preset in presets:
                add_points_link = self.text.make_tellcmd("Add pts", "raid addpts %s" % preset.name)
                blob += "<highlight>%s</highlight> worth <green>%d</green> points %s [id: %d]\n\n" \
                        % (preset.name, preset.points, add_points_link, preset.preset_id)

            return blob

        return "No presets available. To add new presets use <highlight><symbol>presets add preset_name preset_points</highlight>."

    def add_log_entry(self, char_id: int, leader_id: int, reason: str, amount=0):
        sql = "INSERT INTO points_log (char_id, audit, leader_id, reason, created_at) VALUES (?,?,?,?,?)"
        return self.db.exec(sql, [char_id, amount, leader_id, reason, int(time.time())])

    def alter_points(self, char_id: int, leader_id: int, reason: str, amount: int):
        sql = "UPDATE points SET points = points + ? WHERE char_id = ?"
        self.db.exec(sql, [amount, char_id])

        self.add_log_entry(char_id, leader_id, reason, amount)

    def get_account(self, main_id, conn):
        sql = "SELECT p.char_id, p.points, p.disabled FROM points p WHERE p.char_id = ?"
        row = self.db.query_single(sql, [main_id])
        if not row:
            self.create_account(main_id, SenderObj(conn.get_char_id(),
                                                   conn.get_char_name(),
                                                   None))
            row = self.db.query_single(sql, [main_id])

        return row

    def create_account(self, main_id, sender):
        sql = "INSERT INTO points (char_id, points, created_at) VALUES (?,?,?)"
        self.db.exec(sql, [main_id, 0, int(time.time())])

        self.add_log_entry(main_id, sender.char_id, "Account opened by %s" % sender.name)

    def get_account_display(self, char: SenderObj, page):
        main = self.alts_service.get_main(char.char_id)
        if not main:
            return "Could not find character <highlight>%s</highlight>." % char.name

        page = int(page) if page else 1
        page_size = 20
        offset = (page - 1) * page_size

        points = self.db.query_single("SELECT points, disabled FROM points WHERE char_id = ?", [main.char_id])
        if not points:
            return "Could not find raid account for <highlight>%s</highlight>." % char.name

        alts_link = self.text.make_tellcmd("Alts", "alts %s" % main.name)
        blob = ""
        blob += "Account: %s [%s]\n" % (main.name, alts_link)
        blob += "Points: %d\n" % points.points
        blob += "Status: %s\n\n" % ("<green>Open</green>" if points.disabled == 0 else "<red>Disabled</red>")

        points_log = self.db.query("SELECT * FROM points_log WHERE char_id = ? ORDER BY created_at DESC LIMIT ?, ?",
                                   [main.char_id, offset, page_size])
        blob += "<header2>Account log</header2>\n"
        if points_log is None:
            blob += "No entries in log."
        else:
            for entry in points_log:
                if entry.audit > 0:
                    pts = "<green>+%d</green>" % entry.audit
                    blob += "<grey>[%s]</grey> %s points by <highlight>%s</highlight>; <orange>%s</orange>" \
                            % (self.util.format_datetime(entry.created_at), pts,
                               self.character_service.resolve_char_to_name(entry.leader_id), entry.reason)
                elif entry.audit < 0:
                    pts = "<red>-%d</red>" % (-1 * entry.audit)
                    blob += "<grey>[%s]</grey> %s points by <highlight>%s</highlight>; <orange>%s</orange>" \
                            % (self.util.format_datetime(entry.created_at), pts,
                               self.character_service.resolve_char_to_name(entry.leader_id),
                               entry.reason)
                else:
                    # If points is 0, then it's a general case log
                    blob += "<grey>[%s]</grey> <orange>%s</orange>" % (self.util.format_datetime(entry.created_at), entry.reason)

                log_entry_link = self.text.make_tellcmd(entry.log_id, f"account history {entry.log_id}")
                blob += " [%s]\n" % log_entry_link

        return ChatBlob("%s Account" % char.name, blob)
コード例 #19
0
ファイル: auction_controller.py プロジェクト: torkil/Tyrbot
class AuctionController:
    def __init__(self):
        self.auction_running = False
        self.auction_time = None
        self.ignore = False
        self.bidder_accounts = {}
        self.announce_ids = []
        self.announe_anti_ids = []
        self.auction_anti_spam = []

    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.bot: Tyrbot = registry.get_instance("bot")
        self.raid_controller: RaidController = registry.get_instance(
            "raid_controller")
        self.setting_service: SettingService = registry.get_instance(
            "setting_service")
        self.job_scheduler: JobScheduler = registry.get_instance(
            "job_scheduler")
        self.character_service: CharacterService = registry.get_instance(
            "character_service")
        self.alts_service: AltsService = registry.get_instance("alts_service")
        self.points_controller: PointsController = registry.get_instance(
            "points_controller")

    @setting(
        name="vickrey_auction",
        value=False,
        description=
        "If true, the auction procedure will be done in the Vickrey approach")
    def vickrey_auction(self):
        return BooleanSettingType()

    @setting(name="minimum_bid",
             value="2",
             description="Minimum bid required for any bid to be valid")
    def minimum_bid(self):
        return NumberSettingType()

    @setting(name="auction_length",
             value="90",
             description="Regular auction length in seconds")
    def auction_length(self):
        return NumberSettingType()

    @setting(name="auction_announce_interval",
             value="15",
             description="Auction announce interval")
    def auction_announce_interval(self):
        return NumberSettingType()

    @setting(name="mass_auction_length",
             value="180",
             description="Mass auction length in seconds")
    def mass_auction_length(self):
        return NumberSettingType()

    @setting(name="mass_auction_announce_interval",
             value="30",
             description="Mass auction announce interval")
    def mass_auction_announce_interval(self):
        return NumberSettingType()

    @command(command="auction",
             params=[Const("start"), Any("items")],
             description="Start an auction, with one or more items",
             access_level="moderator")
    def auction_start_cmd(self, request, _, items):
        if self.auction_running:
            return "Auction already running."

        items = re.findall(
            "(([^<]+)?<a href=\"itemref://(\d+)/(\d+)/(\d+)\">([^<]+)</a>([^<]+)?)",
            items)

        if items:
            auction_item = None
            for item in items:
                _, prefix, low_id, high_id, ql, name, suffix = item
                auction_item = self.add_auction_item_to_loot(
                    int(low_id), int(high_id), int(ql), name,
                    request.sender.char_id, prefix, suffix, 1)

            if len(self.raid_controller.loot_list) > 1:
                self.bot.send_org_message(
                    "%s just started a mass auction "
                    "for %d items." %
                    (request.sender.name, len(self.raid_controller.loot_list)))
                self.bot.send_private_channel_message(
                    "%s just started a mass auction for %d items." %
                    request.sender.name, len(self.raid_controller.loot_list))
                self.raid_controller.loot_cmd(request)
            else:
                sql = "SELECT winning_bid FROM auction_log WHERE " \
                      "item_name LIKE '%' || ? || '%' ORDER BY time DESC LIMIT 5"
                bids = self.db.query(sql, [auction_item.item.name])
                if bids:
                    avg_win_bid = int(
                        sum(map(lambda x: x.winning_bid, bids)) / len(bids))
                else:
                    avg_win_bid = 0

                bid_link = self.raid_controller.get_auction_list()
                bid_link = self.text.paginate(
                    ChatBlob("Click to bid", bid_link.msg), 5000, 1)[0]
                msg = "\n<yellow>----------------------------------------<end>\n"
                msg += "<yellow>%s<end> has just started an auction " \
                       "for <yellow>%s<end>.\n" % (request.sender.name, auction_item.item.name)
                msg += "Average winning bid: <highlight>%s<end>\n" % avg_win_bid
                msg += "%s\n" % bid_link
                msg += "<yellow>----------------------------------------<end>"

                self.bot.send_private_channel_message(msg)
                self.bot.send_org_message(msg)

            self.auction_running = True
            self.auction_time = int(time.time())
            self.create_auction_timers()

            return

        return "Can't start empty auction."

    @command(command="auction",
             params=[Options(["cancel", "end"])],
             description="Cancel ongoing auction",
             access_level="moderator")
    def auction_cancel_cmd(self, _1, _2):
        if self.auction_running:
            self.auction_running = False
            self.auction_time = None
            self.raid_controller.loot_list.clear()
            self.bidder_accounts.clear()

            for announce_id in self.announce_ids:
                self.job_scheduler.cancel_job(announce_id)

            for announce_id in self.announe_anti_ids:
                self.job_scheduler.cancel_job(announce_id)

            self.announce_ids.clear()
            self.announe_anti_ids.clear()
            self.auction_anti_spam.clear()

            return "Auction canceled."

        return "No auction running."

    @command(command="auction",
             params=[
                 Const("bid"),
                 Int("amount", is_optional=True),
                 Const("all", is_optional=True),
                 Int("item_index", is_optional=True)
             ],
             description="Bid on an item",
             access_level="member",
             sub_command="bid")
    def auction_bid_cmd(self, request, _, amount, all_amount, item_index):
        if not self.auction_running:
            return "No auction in progress."

        if amount or all_amount:
            vickrey = self.setting_service.get("vickrey_auction").get_value()
            minimum_bid = self.setting_service.get("minimum_bid").get_value()
            main_id = self.alts_service.get_main(
                request.sender.char_id).char_id
            item_index = item_index or 1
            new_bidder = False

            try:
                auction_item = self.raid_controller.loot_list[item_index]
            except KeyError:
                return "No item at given index."

            try:
                bidder_account = self.bidder_accounts[main_id]
                t_available = bidder_account.points_available
            except KeyError:
                sql = "SELECT p.points, p.disabled FROM points p WHERE p.char_id = ?"
                t_available = self.db.query_single(sql, [main_id])

                if t_available:
                    if t_available.disabled > 0:
                        return "Your account has been frozen. Contact an admin."

                    t_available = t_available.points
                else:
                    return "You do not have an active account with this bot."

                self.bidder_accounts[main_id] = BidderAccount(
                    main_id, request.sender.char_id, t_available)
                bidder_account = self.bidder_accounts[main_id]

            bidder = next((bidder for bidder in auction_item.bidders
                           if bidder.char_id == request.sender.char_id), None)

            if bidder:
                used = bidder_account.points_used - bidder.bid
                available = t_available - used
            else:
                new_bidder = True
                available = t_available
                used = 0
                bidder = AuctionBid(request.sender.char_id, amount)

            if all_amount:
                amount = available

            if amount > available:
                return "You do not have enough points to make this bid. You have %d points " \
                       "available (%d points on account, %d points reserved for other bids)" \
                       % (available, t_available, used)

            if amount < minimum_bid:
                return "Invalid bid. The minimum allowed bid value is %d." % minimum_bid

            if vickrey:
                if bidder.bid_count < 2:
                    if bidder.bid == amount and not new_bidder:
                        return "The submitted bid matches your current bid. You can only submit a " \
                               "new bid if it's of higher value than the previous bid. This bid did not " \
                               "count against your bid count for this item."
                    if bidder.bid > amount:
                        return "The submitted bid is lower than your current bid. You can only submit a " \
                               "new bid if it's of higher value than the previous bid. This bid did not " \
                               "count against your bid count for this item."

                    bidder.bid_count += 1
                    bidder.bid = amount
                    bidder_account.points_used = used + amount
                    auction_item.second_highest = auction_item.winning_bid \
                        if auction_item.winning_bid > 0 else minimum_bid
                    auction_item.winning_bid = amount
                    auction_item.winner_id = bidder.char_id
                    if new_bidder:
                        auction_item.bidders.append(bidder)

                    bid_count_text = "first" if bidder.bid_count == 1 else "second"
                    return "Your bid of %d points was accepted. This was your %s bid on " \
                           "this item. You have %d points left to use in the ongoing " \
                           "auction." % (amount, bid_count_text, (available - amount))
                else:
                    return "You've already exhausted your allowed bids for this item; as this " \
                       "is a Vickrey auction, you only get to bid twice on the same item."
            else:
                winner_name = self.character_service.resolve_char_to_name(
                    auction_item.winner_id)
                bidder_name = self.character_service.resolve_char_to_name(
                    request.sender.char_id)
                item_name = auction_item.item.name

                if bidder.bid > auction_item.second_highest:
                    auction_item.second_highest = bidder.bid

                if bidder.bid <= auction_item.winning_bid:
                    self.auction_anti_spam.append(
                        "%s's bid of <red>%d<end> points did not exceed the "
                        "current winning bid for %s. %s holds the winning bid."
                        % (bidder_name, bidder.bid, item_name, winner_name))
                    return "Your bid of %d points was not enough. %s is currently " \
                           "winning with a minimum bid of %d." % (bidder.bid, winner_name, auction_item.second_highest)

                if bidder.bid > auction_item.winning_bid:
                    if auction_item.winner_id:
                        prev_main_id = self.alts_service.get_main(
                            auction_item.winner_id).char_id
                        prev_bidder_account = self.bidder_accounts[
                            prev_main_id]
                        print("tot: %d -- used: %d" %
                              (prev_bidder_account.points_available,
                               prev_bidder_account.points_used))
                        prev_bidder_account.points_used -= auction_item.winning_bid
                        print("tot: %d -- used: %d" %
                              (prev_bidder_account.points_available,
                               prev_bidder_account.points_used))
                        new_available = prev_bidder_account.points_available - prev_bidder_account.points_used
                        print("tot: %d -- used: %d -- new avail: %d" %
                              (prev_bidder_account.points_available,
                               prev_bidder_account.points_used, new_available))
                        self.bot.send_private_message(
                            auction_item.winner_id,
                            "Your bid on %s has been overtaken by %s. The points have been returned to your pool of "
                            "available points (%d points)." %
                            (item_name, bidder_name, new_available))

                    auction_item.second_highest = auction_item.winning_bid + 1
                    if auction_item.second_highest == 0:
                        auction_item.second_highest = minimum_bid

                    auction_item.winning_bid = bidder.bid
                    auction_item.winner_id = bidder.char_id

                    if new_bidder:
                        auction_item.bidders.append(bidder)

                    bidder_account.points_used = used + amount
                    new_available = t_available - bidder_account.points_used
                    if len(self.announce_ids) < 2 and len(
                            self.raid_controller.loot_list) == 1:
                        self.job_scheduler.cancel_job(self.announce_ids.pop())
                        self.announce_ids.append(
                            self.job_scheduler.delayed_job(
                                self.auction_results, 10))
                        self.bot.send_org_message(
                            "%s now holds the leading bid for %s. Bid was "
                            "made with less than 10 seconds left of auction, end timer has "
                            "been pushed back 10 seconds." %
                            (bidder_name, item_name))
                        self.bot.send_private_channel_message(
                            "%s now holds the leading bid for %s. Bid was made with "
                            "less than 10 seconds left of auction, end timer has been"
                            " pushed back 10 seconds." %
                            (bidder_name, item_name))
                    else:
                        self.auction_anti_spam.append(
                            "%s now holds the leading bid for %s." %
                            (bidder_name, item_name))
                    return "Your bid of %d points for %s has put you in the lead. " \
                           "You have %d points available for bidding." % (bidder.bid, item_name, new_available)

        return "Invalid bid."

    @command(command="auction",
             params=[Const("bid"),
                     Const("item"),
                     Int("item_index")],
             description="Get bid info for a specific item",
             access_level="member",
             sub_command="bid_info")
    def auction_bid_info_cmd(self, _1, _2, _3, item_index):
        if not self.raid_controller.loot_list:
            return "No auction running."

        blob = ""

        loot_item = self.raid_controller.loot_list[item_index]
        ao_item = loot_item.item
        min_bid = self.setting_service.get("minimum_bid").get_value()

        blob += "To bid for <yellow>%s<end>, you must send a tell to <myname> with\n\n" % ao_item.name
        blob += "<highlight><tab>/tell <myname> auction bid &lt;amount&gt; %d<end>\n\n" % item_index
        blob += "Where you replace &lt;amount&gt; with the amount of points you're willing to bid for the item.\n"
        blob += "Minimum bid is %d. You can also use \"all\" as bid, to bid all your available points.\n\n" % min_bid
        blob += "<highlight>Please note<end> that if you leave out the trailing number, %d. " % item_index
        blob += "It determines the auction item number you're bidding on, "
        blob += "which can be noted on the loot list, in front of the item name.\n\n"
        if self.setting_service.get("vickrey_auction").get_value():
            blob += "<header2>This is a Vickrey auction<end>\n"
            blob += " - In a Vickrey auction, you only get to bid twice on the same item.\n"
            blob += " - You won't be notified of the outcome of your bid, as all bids will be anonymous.\n"
            blob += " - The highest anonymous bid will win, and pay the second-highest bid.\n"
            blob += " - Bids are anonymous; sharing your bid with others defeat the purpose of the Vickrey format.\n"
            blob += " - Bidding is done the same way as regular bids, as described above."

        return ChatBlob("Bid on item %s" % ao_item.name, blob)

    def add_auction_item_to_loot(self,
                                 low_id: int,
                                 high_id: int,
                                 ql: int,
                                 name: str,
                                 auctioneer_id: int,
                                 prefix=None,
                                 suffix=None,
                                 item_count=1):
        end_index = list(self.raid_controller.loot_list.keys())[-1] + 1 if len(
            self.raid_controller.loot_list) > 0 else 1

        item_ref = {
            "low_id": low_id,
            "high_id": high_id,
            "ql": ql,
            "name": name
        }

        self.raid_controller.loot_list[end_index] = AuctionItem(
            item_ref, auctioneer_id, prefix, suffix, item_count)

        return self.raid_controller.loot_list[end_index]

    def create_auction_timers(self):
        if len(self.raid_controller.loot_list) > 1:
            auction_length = self.setting_service.get(
                "mass_auction_length").get_value()
            interval = self.setting_service.get(
                "mass_auction_announce_interval")
        else:
            auction_length = self.setting_service.get(
                "auction_length").get_value()
            interval = self.setting_service.get(
                "auction_announce_interval").get_value()

        iterations = int(
            (auction_length - auction_length % interval) / interval)

        for i in range(1, iterations):
            iteration = i * interval
            time_left = int(auction_length - iteration)
            self.announce_ids.append(
                self.job_scheduler.delayed_job(self.auction_announce,
                                               iteration, time_left))

        for i in range(1, auction_length):
            self.announe_anti_ids.append(
                self.job_scheduler.delayed_job(self.auction_anti_spam_announce,
                                               i))

        if len(self.raid_controller.loot_list) == 1:
            self.announce_ids.append(
                self.job_scheduler.delayed_job(self.auction_results,
                                               auction_length))

    def auction_announce(self, _, time_left):
        if self.auction_running:
            self.announce_ids.pop(0)

            item_count = len(self.raid_controller.loot_list)

            if self.announce_ids and item_count > 1:
                msg = "Auction for %d items running. %d seconds left of auction." % (
                    item_count, time_left)
            elif len(self.raid_controller.loot_list) > 1:
                msg = "Auction for %d items will end within 30 seconds" % item_count
                self.announce_ids.append(
                    self.job_scheduler.delayed_job(
                        self.auction_results, secrets.choice(range(5, 30))))
            else:
                auction_item = list(
                    self.raid_controller.loot_list.values())[-1]
                item = auction_item.item

                if self.setting_service.get("vickrey_auction").get_value():
                    winner = "%d bid(s) have been made." % len(auction_item.bidders) \
                        if auction_item.bidders else "No bids made."
                else:
                    winner_name = self.character_service.resolve_char_to_name(
                        auction_item.winner_id)
                    winner = "%s holds the winning bid." % winner_name \
                        if auction_item.winning_bid > 0 else "No bids made."

                item_ref = self.text.make_item(item.low_id, item.high_id,
                                               item.ql, item.name)
                msg = "Auction for %s running. %s " \
                      "<yellow>%d<end> seconds left of auction." % (item_ref, winner, time_left)

            self.bot.send_private_channel_message(msg)
            self.bot.send_org_message(msg)
            self.raid_controller.loot_cmd(None)

    def auction_anti_spam_announce(self, _):
        announce = None

        if len(self.auction_anti_spam) >= 1:
            announce = self.auction_anti_spam.pop(-1)
            self.auction_anti_spam.clear()

        if announce:
            self.bot.send_org_message(announce)
            self.bot.send_private_channel_message(announce)

    def auction_results(self, _):
        sql = "INSERT INTO auction_log (item_ref, item_name, winner_id, " \
              "auctioneer_id, time, winning_bid, second_highest_bid) VALUES (?,?,?,?,?,?,?)"

        blob = ""

        for i, auction_item in self.raid_controller.loot_list.items():
            was_rolled = False
            if self.setting_service.get("vickrey_auction").get_value():
                was_rolled = self.find_vickrey_winner(auction_item)

            item = auction_item.item
            item_ref = self.text.make_item(item.low_id, item.high_id, item.ql,
                                           item.name)
            prefix = "%s " % auction_item.prefix if auction_item.prefix is not None else ""
            suffix = " %s" % auction_item.suffix if auction_item.prefix is not None else ""
            item_name = "%s%s%s" % (prefix, item.name, suffix)

            if auction_item.winning_bid > 0:
                self.db.exec(sql, [
                    item_ref, item_name, auction_item.winner_id,
                    auction_item.auctioneer_id,
                    int(time.time()), auction_item.winning_bid,
                    auction_item.second_highest
                ])

                winner_name = self.character_service.resolve_char_to_name(
                    auction_item.winner_id)
                was_rolled = " (winner was determined by roll)" if was_rolled else ""
                blob += "%d. %s (ql%d), won by <yellow>%s<end> " \
                        "with <green>%d<end> points%s" \
                        % (i, item_ref, item.ql, winner_name, auction_item.second_highest, was_rolled)
                main_id = self.alts_service.get_main(
                    auction_item.winner_id).char_id
                current_points = self.bidder_accounts[main_id].points_available
                self.points_controller.alter_points(
                    current_points, main_id, -auction_item.second_highest,
                    auction_item.auctioneer_id,
                    "Won auction for %s" % item_name)
            else:
                blob += "%d. %s (ql%d), no bids made" % (i, item_ref, item.ql)

        self.auction_running = False
        self.auction_time = None
        self.bidder_accounts.clear()
        self.announce_ids.clear()
        self.announe_anti_ids.clear()
        self.raid_controller.loot_list.clear()

        result_blob = ChatBlob("Auction results", blob)

        self.bot.send_org_message(result_blob)
        self.bot.send_private_channel_message(result_blob)

    def find_vickrey_winner(self, item: AuctionItem):
        was_rolled = False

        if item.bidders:
            minimum_bid = self.setting_service.get("minimum_bid").get_value()
            vickrey_list = []
            winning_bid = 0
            winner = None

            for bidder in item.bidders:
                if bidder.bid > winning_bid:
                    item.second_highest = winning_bid
                    winning_bid = bidder.bid
                    winner = bidder.char_id
                    vickrey_list.clear()
                elif bidder.bid == winning_bid and winner:
                    # Potential pitfall if winner for some strange reason is None.
                    # It should not be possible to do a bid of 0 or less, so we just
                    # assume that if bid is equal to winning bid, winning bid must be
                    # greater than 0, and thus a winner must exist from a previous
                    # iterated bid
                    vickrey_list.append(bidder.char_id)

            if vickrey_list:
                vickrey_list.append(winner)
                item.second_highest = winning_bid
                winner = secrets.choice(vickrey_list)
                was_rolled = True

            if winning_bid > 0 and winner:
                item.winning_bid = winning_bid
                item.winner_id = winner
                if item.second_highest == 0:
                    item.second_highest = minimum_bid

        return was_rolled
コード例 #20
0
class ConfigCommandController:
    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.access_service = registry.get_instance("access_service")
        self.command_service = registry.get_instance("command_service")

    @command(command="config",
             params=[
                 Const("cmd"),
                 Any("cmd_name"),
                 Options(["enable", "disable"]),
                 Any("channel")
             ],
             access_level="admin",
             description="Enable or disable a command")
    def config_cmd_status_cmd(self, request, _, cmd_name, action, cmd_channel):
        cmd_name = cmd_name.lower()
        action = action.lower()
        cmd_channel = cmd_channel.lower()
        command_str, sub_command_str = self.command_service.get_command_key_parts(
            cmd_name)
        enabled = 1 if action == "enable" else 0

        if cmd_channel != "all" and not self.command_service.is_command_channel(
                cmd_channel):
            return "Unknown command channel <highlight>%s<end>." % cmd_channel

        sql = "UPDATE command_config SET enabled = ? WHERE command = ? AND sub_command = ?"
        params = [enabled, command_str, sub_command_str]
        if cmd_channel != "all":
            sql += " AND channel = ?"
            params.append(cmd_channel)

        count = self.db.exec(sql, params)
        if count == 0:
            return "Could not find command <highlight>%s<end> for channel <highlight>%s<end>." % (
                cmd_name, cmd_channel)
        else:
            if cmd_channel == "all":
                return "Command <highlight>%s<end> has been <highlight>%sd<end> successfully." % (
                    cmd_name, action)
            else:
                return "Command <highlight>%s<end> for channel <highlight>%s<end> has been <highlight>%sd<end> successfully." % (
                    cmd_name, cmd_channel, action)

    @command(command="config",
             params=[
                 Const("cmd"),
                 Any("cmd_name"),
                 Const("access_level"),
                 Any("channel"),
                 Any("access_level")
             ],
             access_level="admin",
             description="Change access_level for a command")
    def config_cmd_access_level_cmd(self, request, _1, cmd_name, _2,
                                    cmd_channel, access_level):
        cmd_name = cmd_name.lower()
        cmd_channel = cmd_channel.lower()
        access_level = access_level.lower()
        command_str, sub_command_str = self.command_service.get_command_key_parts(
            cmd_name)

        if cmd_channel != "all" and not self.command_service.is_command_channel(
                cmd_channel):
            return "Unknown command channel <highlight>%s<end>." % cmd_channel

        if self.access_service.get_access_level_by_label(access_level) is None:
            return "Unknown access level <highlight>%s<end>." % access_level

        sql = "UPDATE command_config SET access_level = ? WHERE command = ? AND sub_command = ?"
        params = [access_level, command_str, sub_command_str]
        if cmd_channel != "all":
            sql += " AND channel = ?"
            params.append(cmd_channel)

        count = self.db.exec(sql, params)
        if count == 0:
            return "Could not find command <highlight>%s<end> for channel <highlight>%s<end>." % (
                cmd_name, cmd_channel)
        else:
            if cmd_channel == "all":
                return "Access level <highlight>%s<end> for command <highlight>%s<end> has been set successfully." % (
                    access_level, cmd_name)
            else:
                return "Access level <highlight>%s<end> for command <highlight>%s<end> on channel <highlight>%s<end> has been set successfully." % (
                    access_level, cmd_name, cmd_channel)

    @command(command="config",
             params=[Const("cmd"), Any("cmd_name")],
             access_level="admin",
             description="Show command configuration")
    def config_cmd_show_cmd(self, request, _, cmd_name):
        cmd_name = cmd_name.lower()
        command_str, sub_command_str = self.command_service.get_command_key_parts(
            cmd_name)

        blob = ""
        for command_channel, channel_label in self.command_service.channels.items(
        ):
            cmd_configs = self.command_service.get_command_configs(
                command=command_str,
                sub_command=sub_command_str,
                channel=command_channel,
                enabled=None)
            if len(cmd_configs) > 0:
                cmd_config = cmd_configs[0]
                if cmd_config.enabled == 1:
                    status = "<green>Enabled<end>"
                else:
                    status = "<red>Disabled<end>"

                blob += "<header2>%s<end> %s (Access Level: %s)\n" % (
                    channel_label, status,
                    cmd_config.access_level.capitalize())

                # show status config
                blob += "Status:"
                enable_link = self.text.make_chatcmd(
                    "Enable", "/tell <myname> config cmd %s enable %s" %
                    (cmd_name, command_channel))
                disable_link = self.text.make_chatcmd(
                    "Disable", "/tell <myname> config cmd %s disable %s" %
                    (cmd_name, command_channel))

                blob += "  " + enable_link + "  " + disable_link

                # show access level config
                blob += "\nAccess Level:"
                for access_level in self.access_service.access_levels:
                    # skip "None" access level
                    if access_level["level"] == 0:
                        continue

                    label = access_level["label"]
                    link = self.text.make_chatcmd(
                        label.capitalize(),
                        "/tell <myname> config cmd %s access_level %s %s" %
                        (cmd_name, command_channel, label))
                    blob += "  " + link
                blob += "\n\n\n"

        if blob:
            # include help text
            blob += "\n\n".join(
                map(lambda handler: handler["help"],
                    self.command_service.get_handlers(cmd_name)))
            return ChatBlob("Command (%s)" % cmd_name, blob)
        else:
            return "Could not find command <highlight>%s<end>." % cmd_name
コード例 #21
0
class AlienArmorController:
    def inject(self, registry):
        self.text: Text = registry.get_instance("text")
        self.items_controller = registry.get_instance("items_controller")

    @command(command="aiarmor",
             params=[],
             access_level="all",
             description="List the alien armor types")
    def aiarmor_list_command(self, request):
        blob = ""
        blob += "<highlight>Normal Armor:<end>\n"
        blob += self.text.make_chatcmd("Strong Armor",
                                       "/tell <myname> aiarmor Strong") + "\n"
        blob += self.text.make_chatcmd("Supple Armor",
                                       "/tell <myname> aiarmor Supple") + "\n"
        blob += self.text.make_chatcmd(
            "Enduring Armor", "/tell <myname> aiarmor Enduring") + "\n"
        blob += self.text.make_chatcmd(
            "Observant Armor", "/tell <myname> aiarmor Observant") + "\n"
        blob += self.text.make_chatcmd(
            "Arithmetic Armor", "/tell <myname> aiarmor Arithmetic") + "\n"
        blob += self.text.make_chatcmd(
            "Spiritual Armor", "/tell <myname> aiarmor Spiritual") + "\n"
        blob += "\n<highlight>Combined Armor:<end>\n"
        blob += self.text.make_chatcmd("Combined Commando's Armor",
                                       "/tell <myname> aiarmor cc") + "\n"
        blob += self.text.make_chatcmd("Combined Mercenary's Armor",
                                       "/tell <myname> aiarmor cm") + "\n"
        blob += self.text.make_chatcmd("Combined Officer's",
                                       "/tell <myname> aiarmor co") + "\n"
        blob += self.text.make_chatcmd("Combined Paramedic's Armor",
                                       "/tell <myname> aiarmor cp") + "\n"
        blob += self.text.make_chatcmd("Combined Scout's Armor",
                                       "/tell <myname> aiarmor cs") + "\n"
        blob += self.text.make_chatcmd("Combined Sharpshooter's Armor",
                                       "/tell <myname> aiarmor css")

        return ChatBlob("Alien Armor", blob)

    @command(command="aiarmor",
             params=[
                 Options([
                     "strong", "supple", "enduring", "observant", "arithmetic",
                     "spiritual"
                 ]),
                 Int("ql", is_optional=True)
             ],
             access_level="all",
             description="Show the process for making normal alien armor")
    def aiarmor_normal_command(self, request, armor_type, ql):
        armor_type = armor_type.capitalize()
        ql = ql or 300
        misc_ql = math.floor(ql * 0.8)

        blob = "Note: All tradeskill processes are based on the lowest QL items usable.\n\n"
        blob += "<header2>You need the following items to build %s Armor:<end>\n" % armor_type
        blob += "- Kyr'Ozch Viralbots\n"
        blob += "- Kyr'Ozch Atomic Re-Structulazing Tool\n"
        blob += "- Solid Clump of Kyr'Ozch Biomaterial\n"
        blob += "- Arithmetic/Strong/Enduring/Spiritual/Observant/Supple Viralbots\n\n"

        blob += "<header2>Step 1<end>\n"
        blob += "<tab>%s (<highlight>Drops from Alien City Generals<end>)\n" % self.display_item_by_name(
            "Kyr'Ozch Viralbots", misc_ql)
        blob += "<tab><tab>+\n"
        blob += "<tab>%s (<highlight>Drops from every Alien<end>)\n" % self.display_item_by_name(
            "Kyr'Ozch Atomic Re-Structuralizing Tool", 100)
        blob += "<tab><tab>=\n"
        blob += "<tab>%s\n" % self.display_item_by_name(
            "Memory-Wiped Kyr'Ozch Viralbots", misc_ql)
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Computer Literacy\n" % math.ceil(misc_ql * 4.5)
        blob += "- %d Nano Programming\n\n" % math.ceil(misc_ql * 4.5)

        blob += "<header2>Step 2<end>\n"
        blob += "<tab>%s (<highlight>Can be bought in General Shops<end>)\n" % self.display_item_by_name(
            "Nano Programming Interface", 1)
        blob += "<tab><tab>+\n"
        blob += "<tab>%s\n" % self.display_item_by_name(
            "Memory-Wiped Kyr'Ozch Viralbots", misc_ql)
        blob += "<tab><tab>=\n"
        blob += "<tab>%s\n" % self.display_item_by_name(
            "Formatted Kyr'Ozch Viralbots", misc_ql)
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Computer Literacy\n" % math.ceil(misc_ql * 4.5)
        blob += "- %d Nano Programming\n\n" % math.ceil(misc_ql * 6)

        blob += "<header2>Step 3<end>\n"
        blob += "<tab>%s\n" % self.display_item_by_name(
            "Kyr'Ozch Structural Analyzer", 100)
        blob += "<tab><tab>+\n"
        blob += "<tab>%s QL%d (<highlight>Drops from every Alien<end>)\n" % (
            self.display_item_by_name("Solid Clump of Kyr'Ozch Bio-Material",
                                      ql), ql)
        blob += "<tab><tab>=\n"
        blob += "<tab>%s QL%d" % (self.display_item_by_name(
            "Mutated Kyr'Ozch Bio-Material", ql), ql)
        blob += "\n\nor\n\n<tab>%s QL%d\n" % (self.display_item_by_name(
            "Pristine Kyr'Ozch Bio-Material", ql), ql)
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Chemistry (Both require the same amount)\n\n" % math.ceil(
            ql * 4.5)

        blob += "<header2>Step 4<end>\n"
        blob += "<tab>%s QL%d" % (self.display_item_by_name(
            "Mutated Kyr'Ozch Bio-Material", ql), ql)
        blob += "\n\nor\n\n<tab>%s QL%d\n" % (self.display_item_by_name(
            "Pristine Kyr'Ozch Bio-Material", ql), ql)
        blob += "<tab><tab>+\n"
        blob += "<tab>%s (<highlight>Can be bought in Bazzit Shop in MMD<end>)\n" % self.display_item_by_name(
            "Uncle Bazzit's Generic Nano-Solvent", 100)
        blob += "<tab><tab>=\n"
        blob += "<tab>%s\n" % self.display_item_by_name(
            "Generic Kyr'Ozch DNA-Soup", ql)
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Chemistry(for Pristine)\n" % math.ceil(ql * 4.5)
        blob += "- %d Chemistry(for Mutated)\n\n" % math.ceil(ql * 7)

        blob += "<header2>Step 5<end>\n"
        blob += "<tab>" + self.display_item_by_name(
            "Generic Kyr'Ozch DNA-Soup", ql) + "\n"
        blob += "<tab><tab>+\n"
        blob += "<tab>" + self.display_item_by_name(
            "Essential Human DNA",
            100) + " (<highlight>Can be bought in Bazzit Shop in MMD<end>)\n"
        blob += "<tab><tab>=\n"
        blob += "<tab>" + self.display_item_by_name("DNA Cocktail", ql) + "\n"
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Pharma Tech\n\n" % math.ceil(ql * 6)

        blob += "<header2>Step 6<end>\n"
        blob += "<tab>" + self.display_item_by_name(
            "Formatted Kyr'Ozch Viralbots", misc_ql) + "\n"
        blob += "<tab><tab>+\n"
        blob += "<tab>" + self.display_item_by_name("DNA Cocktail", ql) + "\n"
        blob += "<tab><tab>=\n"
        blob += "<tab>" + self.display_item_by_name(
            "Kyr'Ozch Formatted Viralbot Solution", ql) + "\n"
        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Pharma Tech\n\n" % math.ceil(ql * 6)

        blob += "<header2>Step 7<end>\n"
        blob += "<tab>" + self.display_item_by_name(
            "Kyr'Ozch Formatted Viralbot Solution", ql) + "\n"
        blob += "<tab><tab>+\n"
        blob += "<tab>" + self.display_item_by_name(
            "Basic Fashion Vest", 1
        ) + " (<highlight>Can be obtained by the Basic Armor Quest<end>)\n"
        blob += "<tab><tab>=\n"
        blob += "<tab>" + self.display_item_by_name("Formatted Viralbot Vest",
                                                    ql) + "\n\n"

        blob += "<header2>Step 8<end>\n"

        vb_ql = math.floor(ql * 0.8)
        if armor_type == "Arithmetic":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Arithmetic Lead Viralbots",
                                          vb_ql), vb_ql)
        elif armor_type == "Supple":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Supple Lead Viralbots",
                                          vb_ql), vb_ql)
        elif armor_type == "Enduring":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Enduring Lead Viralbots",
                                          vb_ql), vb_ql)
        elif armor_type == "Observant":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Observant Lead Viralbots",
                                          vb_ql), vb_ql)
        elif armor_type == "Strong":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Strong Lead Viralbots",
                                          vb_ql), vb_ql)
        elif armor_type == "Spiritual":
            blob += "<tab>%s QL%d (<highlight>Rare Drop off Alien City Generals<end>)\n" % (
                self.display_item_by_name("Spiritual Lead Viralbots",
                                          vb_ql), vb_ql)

        blob += "<tab><tab>+\n"
        blob += "<tab>" + self.display_item_by_name("Formatted Viralbot Vest",
                                                    ql) + "\n"
        blob += "<tab><tab>=\n"

        if armor_type == "Arithmetic":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Arithmetic Body Armor", ql), ql)
        elif armor_type == "Supple":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Supple Body Armor", ql), ql)
        elif armor_type == "Enduring":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Enduring Body Armor", ql), ql)
        elif armor_type == "Observant":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Observant Body Armor", ql), ql)
        elif armor_type == "Strong":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Strong Body Armor", ql), ql)
        elif armor_type == "Spiritual":
            blob += "<tab>%s QL%d\n" % (self.display_item_by_name(
                "Spiritual Body Armor", ql), ql)

        blob += "<highlight>Required Skills:<end>\n"
        blob += "- %d Psychology\n\n" % math.floor(ql * 6)

        return ChatBlob("Building process for %d %s" % (ql, armor_type), blob)

    @command(
        command="aiarmor",
        params=[
            Options(["cc", "cm", "co", "cp", "cs", "css", "ss"]),
            Int("ql", is_optional=True)
        ],
        access_level="all",
        description="Show the process for making combined alien armor",
        extended_description="CSS and SS both refer to Combined Sharpshooters")
    def aiarmor_combined_command(self, request, armor_type, target_ql):
        armor_type = armor_type.lower()
        target_ql = target_ql or 300
        source_ql = math.floor(target_ql * 0.8)

        if armor_type == "cc":
            result_armor_id = 246660  # Combined Commando's Jacket

            source_armor_id = 246616  # Strong Body Armor
            name_source = "strong"

            target_armor_id = 246622  # Supple Body Armor
            name_target = "supple"
        elif armor_type == "cm":
            result_armor_id = 246638  # Combined Mercenary's Jacket

            source_armor_id = 246616  # Strong Body Armor
            name_source = "strong"

            target_armor_id = 246580  # Enduring Body Armor
            name_target = "enduring"
        elif armor_type == "co":
            result_armor_id = 246672  # Combined Officer's Jacket

            source_armor_id = 246600  # Spiritual Body Armor
            name_source = "spiritual"

            target_armor_id = 246560  # Arithmetic Body Armor
            name_target = "arithmetic"
        elif armor_type == "cp":
            result_armor_id = 246648  # Combined Paramedic's Jacket

            source_armor_id = 246600  # Spiritual Body Armor
            name_source = "spiritual"

            target_armor_id = 246580  # Enduring Body Armor
            name_target = "enduring"
        elif armor_type == "cs":
            result_armor_id = 246684  # Combined Scout's Jacket

            source_armor_id = 246592  # Observant Body Armor
            name_source = "observant"

            target_armor_id = 246560  # Arithmetic Body Armor
            name_target = "arithmetic"
        elif armor_type == "css" or armor_type == "ss":
            result_armor_id = 246696  # Combined Sharpshooter's Jacket

            source_armor_id = 246592  # Observant Body Armor
            name_source = "observant"

            target_armor_id = 246622  # Supple Body Armor
            name_target = "supple"
        else:
            return "Unknown armor type <highlight>%s<end>" % armor_type

        result_item = self.items_controller.get_by_item_id(result_armor_id)

        blob = "<header2>Result<end>\n"
        blob += "%s QL%d\n\n" % (self.text.format_item(result_item,
                                                       target_ql), target_ql)

        blob += "<header2>Source Armor<end>\n"
        blob += "%s QL%d" % (self.text.format_item(
            self.items_controller.get_by_item_id(source_armor_id),
            target_ql), source_ql)
        blob += " (%s)\n\n" % self.text.make_chatcmd(
            "Tradeskill process for this item",
            "/tell <myname> aiarmor %s %d" % (name_source, source_ql))

        blob += "<header2>Target Armor<end>\n"
        blob += "%s QL%d" % (self.text.format_item(
            self.items_controller.get_by_item_id(target_armor_id),
            target_ql), target_ql)
        blob += " (%s)" % self.text.make_chatcmd(
            "Tradeskill process for this item",
            "/tell <myname> aiarmor %s %d" % (name_target, target_ql))

        return ChatBlob(
            "Building process for %d %s" % (target_ql, result_item.name), blob)

    def display_item_by_name(self, name, ql):
        return self.text.format_item(
            self.items_controller.find_by_name(name, ql), ql)
コード例 #22
0
class AlienGeneralController:
    def inject(self, registry):
        self.text: Text = registry.get_instance("text")
        self.items_controller = registry.get_instance("items_controller")
        self.ts: TranslationService = registry.get_instance(
            "translation_service")
        self.getresp = self.ts.get_response

    @command(command="aigen",
             params=[],
             access_level="all",
             description="List alien city ground generals")
    def aigen_list_command(self, request):
        blob = ""
        blob += " - <a href='chatcmd:///tell <myname> aigen Ankari'>Ankari</a>\n"
        blob += " - <a href='chatcmd:///tell <myname> aigen Ilari'>Ilari</a>\n"
        blob += " - <a href='chatcmd:///tell <myname> aigen Rimah'>Rimah</a>\n"
        blob += " - <a href='chatcmd:///tell <myname> aigen Jaax'>Jaax</a>\n"
        blob += " - <a href='chatcmd:///tell <myname> aigen Xoch'>Xoch</a>\n"
        blob += " - <a href='chatcmd:///tell <myname> aigen Cha'>Cha</a>\n"

        return ChatBlob(self.getresp("module/alien", "ai_gen_list_title"),
                        blob)

    @command(
        command="aigen",
        params=[Options(["ankari", "ilari", "rimah", "jaax", "xoch", "cha"])],
        access_level="all",
        description="Show info about an alien city ground general")
    def aigen_show_command(self, request, general):
        general = general.capitalize()

        blob = ""

        if general == "Ankari":
            blob += "Low Evade/Dodge, Low AR, Casts Viral/Virral nukes\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247145)) + "\n"  # Arithmetic Lead Viralbots
            blob += "(Nanoskill / Tradeskill)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247684)) + "\n\n"  # type 1
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247686)) + "\n\n"  # type 2
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(288673))  # type 48
        elif general == "Ilari":
            blob += "Low Evade/Dodge\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247147)) + "\n"  # Spiritual Lead Viralbots
            blob += "(Nanocost / Nanopool / Max Nano)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247682)) + "\n\n"  # type 992
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(247680))  # type 880
        elif general == "Rimah":
            blob += "Low Evade/Dodge\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247143)) + "\n"  # Observant Lead Viralbots
            blob += "(Init / Evades)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247676)) + "\n\n"  # type 112
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(247678))  # type 240
        elif general == "Jaax":
            blob += "High Evade, Low Dodge\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247139)) + "\n"  # Strong Lead Viralbots
            blob += "(Melee / Spec Melee / Add All Def / Add Damage)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247694)) + "\n\n"  # type 3
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(247688))  # type 4
        elif general == "Xoch":
            blob += "High Evade/Dodge, Casts Ilari Biorejuvenation heals\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247137)) + "\n"  # Enduring Lead Viralbots
            blob += "(Max Health / Body Dev)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247690)) + "\n\n"  # type 5
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(247692))  # type 12
        elif general == "Cha":
            blob += "High Evade/NR, Low Dodge\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247141)) + "\n"  # Supple Lead Viralbots
            blob += "(Ranged / Spec Ranged / Add All Off)\n\n"
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(
                    247696)) + "\n\n"  # type 13
            blob += self.text.format_item(
                self.items_controller.get_by_item_id(247674))  # type 76

        return ChatBlob("General %s" % general, blob)
コード例 #23
0
class ConfigEventsController:
    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.command_service = registry.get_instance("command_service")
        self.event_service = registry.get_instance("event_service")
        self.setting_service = registry.get_instance("setting_service")
        self.ts: TranslationService = registry.get_instance("translation_service")
        self.getresp = self.ts.get_response

    @command(command="config", params=[Const("event"), Any("event_type"), Any("event_handler"), Options(["enable", "disable"])], access_level="admin",
             description="Enable or disable an event")
    def config_event_status_cmd(self, request, _, event_type, event_handler, action):
        event_type = event_type.lower()
        event_handler = event_handler.lower()
        action = action.lower()
        event_base_type, event_sub_type = self.event_service.get_event_type_parts(event_type)
        enabled = 1 if action == "enable" else 0

        if not self.event_service.is_event_type(event_base_type):
            return self.getresp("module/config", "unknown event", {"type", event_type})

        count = self.event_service.update_event_status(event_base_type, event_sub_type, event_handler, enabled)

        if count == 0:
            return self.getresp("module/config", "event_enable_fail", {"type": event_type, "handler": event_handler})
        else:
            action = self.getresp("module/config", "enabled_high" if action == "enable" else "disabled_high")
            return self.getresp("module/config", "event_enable_success", {"type": event_type,
                                                                          "handler": event_handler,
                                                                          "changedto": action})

    @command(command="config", params=[Const("event"), Any("event_type"), Any("event_handler"), Const("run")], access_level="admin",
             description="Execute a timed event immediately")
    def config_event_run_cmd(self, request, _1, event_type, event_handler, _2):
        action = "run"
        event_type = event_type.lower()
        event_handler = event_handler.lower()
        event_base_type, event_sub_type = self.event_service.get_event_type_parts(event_type)

        if not self.event_service.is_event_type(event_base_type):
            return self.getresp("module/config", "unknown event", {"type", event_type})

        row = self.db.query_single("SELECT e.event_type, e.event_sub_type, e.handler, t.next_run FROM timer_event t "
                                   "JOIN event_config e ON t.event_type = e.event_type AND t.handler = e.handler "
                                   "WHERE e.event_type = ? AND e.event_sub_type = ? AND e.handler LIKE ?", [event_base_type, event_sub_type, event_handler])

        if not row:
            return self.getresp("module/config", "event_enable_fail", {"type": event_type, "handler": event_handler})
        elif row.event_type != "timer":
            return self.getresp("module/config", "event_manual")
        else:
            self.event_service.execute_timed_event(row, int(time.time()))
            action = self.getresp("module/config", "run")
            return self.getresp("module/config", "event_enable_success", {"type": event_type,
                                                                          "handler": event_handler,
                                                                          "changedto": action})

    @command(command="config", params=[Const("eventlist")], access_level="admin",
             description="List all events")
    def config_eventlist_cmd(self, request, _):
        sql = "SELECT module, event_type, event_sub_type, handler, description, enabled FROM event_config WHERE is_hidden = 0"
        sql += " ORDER BY module, event_type, event_sub_type, handler"
        data = self.db.query(sql)

        blob = ""
        current_module = ""
        for row in data:
            if current_module != row.module:
                blob += "\n<pagebreak><header2>%s<end>\n" % row.module
                current_module = row.module

            event_type_key = self.format_event_type(row)

            on_link = self.text.make_chatcmd("On", "/tell <myname> config event %s %s enable" % (event_type_key, row.handler))
            off_link = self.text.make_chatcmd("Off", "/tell <myname> config event %s %s disable" % (event_type_key, row.handler))

            blob += "%s [%s] %s %s - %s\n" % (event_type_key, self.format_enabled(row.enabled), on_link, off_link, row.description)

        return ChatBlob(self.getresp("module/config", "blob_events", {"amount": len(data)}), blob)

    def format_enabled(self, enabled):
        return "<green>E<end>" if enabled else "<red>D<end>"

    def format_event_type(self, row):
        if row.event_sub_type:
            return row.event_type + ":" + row.event_sub_type
        else:
            return row.event_type
コード例 #24
0
class PointsController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot: Tyrbot = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.character_service: CharacterService = registry.get_instance(
            "character_service")
        self.util: Util = registry.get_instance("util")
        self.setting_service: SettingService = registry.get_instance(
            "setting_service")
        self.alts_service: AltsService = registry.get_instance("alts_service")

    def start(self):
        if self.db.query_single(
                "SELECT COUNT(*) AS count FROM points_presets").count < 1:
            # Populate with pre-made presets if empty
            presets = [
                "s13", "s28", "s35", "s42", "zodiac", "zod", "tnh", "beast",
                "12m", "tara", "pvp", "towers", "wipe", "clanwipe", "clan",
                "omniwipe", "omni", "bonus", "early"
            ]
            sql = "INSERT INTO points_presets (name) VALUES (?)"
            for preset in presets:
                self.db.exec(sql, [preset])

    @setting(name="initial_points_value",
             value="0",
             description="How many points new accounts start with")
    def initial_points_value(self):
        return NumberSettingType()

    @command(command="account",
             params=[Const("create"), Character("char")],
             access_level="moderator",
             description="Create a new account for given character name",
             sub_command="modify")
    def bank_create_cmd(self, request, _, char: SenderObj):
        alts_info = self.alts_service.get_alts(char.char_id)

        for alt in alts_info:
            sql = "SELECT char_id, disabled FROM points WHERE char_id = ? LIMIT 1"
            count = self.db.query_single(sql, [alt.char_id])

            if count:
                was_disabled = False

                if count.disabled == 1:
                    if self.db.exec(
                            "UPDATE points SET disabled = 0 WHERE char_id = ?",
                        [alt.char_id]):
                        was_disabled = True

                if alt.char_id == char.char_id:
                    if was_disabled:
                        if self.add_log_entry(
                                alt.char_id, request.sender.char_id,
                                "Account was re-enabled by %s" %
                                self.character_service.resolve_char_to_name(
                                    request.sender.char_id)):
                            return "<highlight>%s<end>'s account has been re-enabled." % char.name
                        else:
                            return "<highlight>%s<end> has an account, but failed to re-enable it." % char.name
                    else:
                        return "<highlight>%s<end> already has an account." % char.name
                else:
                    if was_disabled:
                        if self.add_log_entry(
                                alt.char_id, request.sender.char_id,
                                "Account was re-enabled by %s" %
                                self.character_service.resolve_char_to_name(
                                    request.sender.char_id)):
                            return "<highlight>%s<end>'s (%s) account has been re-enabled." % (
                                char.name,
                                self.character_service.resolve_char_to_name(
                                    alt.char_id))
                        else:
                            return "<highlight>%s<end> (%s) has an account, but failed to re-enable it." % (
                                char.name,
                                self.character_service.resolve_char_to_name(
                                    alt.char_id))
                    else:
                        return "<highlight>%s<end> (%s) already has an account." % (
                            char.name,
                            self.character_service.resolve_char_to_name(
                                alt.char_id))

        main_info = alts_info.pop(0)
        changed_to_main = main_info.char_id == char.char_id

        initial_points = self.setting_service.get(
            "initial_points_value").get_value()

        sql = "INSERT INTO points (char_id, points, created) VALUES (?,?,?)"
        if self.db.exec(sql,
                        [main_info.char_id, initial_points,
                         int(time.time())]) < 1:
            return "Failed to create an account for <highlight>%s<end>." % char.name

        if not self.add_log_entry(
                main_info.char_id, request.sender.char_id,
                "Account opened by %s" % request.sender.name):
            sql = "DELETE FROM points WHERE char_id = ?"
            self.db.exec(sql, [main_info.char_id])
            return "Failed to create an account for <highlight>%s<end>." % char.name

        name_reference = "%s (%s)" % (
            char.name,
            self.character_service.resolve_char_to_name(
                main_info.char_id)) if changed_to_main else char.name
        return "A new account has been created for <highlight>%s<end>." % name_reference

    @command(command="account",
             params=[Const("close"), Character("char")],
             access_level="moderator",
             description="Close the account for given character name",
             sub_command="modify")
    def close_account_cmd(self, request, _, char: SenderObj):
        main_id = self.alts_service.get_main(char.char_id)

        sql = "UPDATE points SET disabled = 1 WHERE char_id = ?"
        if self.db.exec(sql, [main_id.char_id]) > 0:
            reason = "Account was closed by %s" % self.character_service.resolve_char_to_name(
                request.sender.char_id)
            if self.add_log_entry(main_id.char_id, request.sender.char_id,
                                  reason):
                name_reference = "%s (%s)" % (
                    char.name,
                    self.character_service.resolve_char_to_name(
                        main_id.char_id)
                ) if main_id.char_id != char.char_id else char.name
                return "<highlight>%s<end> has had their account disabled. Logs have been preserved." % name_reference

        return "<highlight>%s<end> does not have an open account." % char.name

    @command(command="account",
             params=[],
             access_level="all",
             description="Look up your account")
    def account_self_cmd(self, request):
        return self.get_account_display(request.sender)

    @command(command="account",
             params=[Const("logentry"), Int("log_id")],
             access_level="moderator",
             description="Look up specific log entry",
             sub_command="modify")
    def account_log_entry_cmd(self, _1, _2, log_id: int):
        log_entry = self.db.query_single(
            "SELECT * FROM points_log WHERE log_id = ?", [log_id])

        if log_entry:
            char_name = self.character_service.resolve_char_to_name(
                log_entry.char_id)
            leader_name = self.character_service.resolve_char_to_name(
                log_entry.leader_id)

            blob = "Log entry ID: <highlight>%d<end>\n" % log_id
            blob += "Affecting account: <highlight>%s<end>\n" % char_name
            blob += "Action by: <highlight>%s<end>\n" % leader_name
            blob += "Type: <highlight>%s<end>\n" % (
                "Management" if log_entry.audit == 0 else "Altering of points")
            blob += "Reason: <highlight>%s<end>\n" % log_entry.reason
            action_links = None
            if log_entry.audit == 0:
                if "closed" in log_entry.reason:
                    action_links = self.text.make_chatcmd(
                        "Open the account",
                        "/tell <myname> account create %s" % char_name)
                elif "re-enabled" in log_entry.reason:
                    action_links = self.text.make_chatcmd(
                        "Close the account",
                        "/tell <myname> account close %s" % char_name)
            else:
                if log_entry.audit < 0:
                    reason = "Points from event (%d) has been retracted, %d points have been added." \
                             % (log_id, (-1*log_entry.audit))
                    action_links = self.text.make_chatcmd(
                        "Retract", "/tell <myname> bank give %d %s %s" %
                        ((-1 * log_entry.audit), char_name, reason))
                else:
                    reason = "Points from event (%d) has been retracted, %d points have been deducted." \
                             % (log_id, log_entry.audit)
                    action_links = self.text.make_chatcmd(
                        "Retract", "/tell <myname> bank take %d %s %s" %
                        (log_entry.audit, char_name, reason))

            blob += "Actions available: [%s]\n" % (action_links
                                                   if action_links is not None
                                                   else "No actions available")

            return ChatBlob("Log entry (%d)" % log_id, blob)

        return "No log entry with given ID <highlight>%d<end>." % log_id

    @command(command="account",
             params=[
                 Options(["give", "take"]),
                 Int("amount"),
                 Character("char"),
                 Any("reason")
             ],
             access_level="moderator",
             description="Give or take points from character account",
             sub_command="modify")
    def account_give_take_cmd(self, request, action: str, amount: int,
                              char: SenderObj, reason: str):
        main_id = self.alts_service.get_main(char.char_id)

        sql = "SELECT * FROM points WHERE char_id = ?"
        points = self.db.query_single(sql, [main_id.char_id])

        if points:
            if points.disabled == 1:
                return "<highlight>%s<end>'s account is disabled, altering the account is not possible." % char.name

            if points.points == 0 and action == "take":
                return "<highlight>%s<end> has 0 points - can't have less than 0 points." % char.name

            if amount > points.points and action == "take":
                amount = points.points

            new_points = amount if action == "give" else 0 - amount

            if not self.alter_points(points.points, main_id.char_id,
                                     new_points, request.sender.char_id,
                                     reason):
                return "Failed to alter <highlight>%s<end>'s account." % char.name

            action = "taken from" if action == "take" else "added to"
            return "<highlight>%s<end> has had <highlight>%d<end> points %s their account." % (
                char.name, amount, action)

        return "<highlight>%s<end> does not have an account." % char.name

    @command(command="account",
             params=[Character("char")],
             access_level="moderator",
             description="Look up account of another char",
             sub_command="modify")
    def account_other_cmd(self, request, char: SenderObj):
        return self.get_account_display(char)

    @command(command="presets",
             params=[Const("add"), Any("name"),
                     Int("points")],
             access_level="admin",
             description="Add new points preset")
    def presets_add_cmd(self, _1, _2, name: str, points: int):
        count = self.db.query_single(
            "SELECT COUNT(*) AS count FROM points_presets WHERE name = ?",
            [name]).count

        if count > 0:
            return "A preset already exists with the name <highlight>%s<end>." % name

        sql = "INSERT INTO points_presets (name, points) VALUES (?,?)"
        if self.db.exec(sql, [name, points]) > 0:
            return "A preset with the name <highlight>%s<end> was added, worth <green>%d<end> points." % (
                name, points)

        return "Failed to insert new preset in DB."

    @command(command="presets",
             params=[Const("rem"), Int("preset_id")],
             access_level="admin",
             description="Delete preset")
    def presets_rem_cmd(self, _1, _2, preset_id: int):
        if self.db.exec("DELETE FROM points_presets WHERE preset_id = ?",
                        [preset_id]) > 0:
            return "Successfully removed preset with ID <highlight>%d<end>." % preset_id

        return "No preset with given ID <highlight>%d<end>." % preset_id

    @command(command="presets",
             params=[Const("alter"),
                     Int("preset_id"),
                     Int("new_points")],
             access_level="admin",
             description="Alter the points dished out by given preset")
    def presets_alter_cmd(self, _1, _2, preset_id: int, new_points: int):
        preset = self.db.query_single(
            "SELECT * FROM points_presets WHERE preset_id = ?", [preset_id])

        if preset:
            if self.db.exec(
                    "UPDATE points_presets SET points = ? WHERE preset_id = ?",
                [new_points, preset_id]) > 0:
                return "Successfully updated the preset, <highlight>%s<end>, to dish out " \
                       "<green>%d<end> points instead of <red>%d<end>." % (preset.name, new_points, preset.points)

            return "Failed to update preset with ID <highlight>%d<end>." % preset_id

    @command(command="presets",
             params=[],
             access_level="admin",
             description="See list of points presets")
    def presets_cmd(self, _):
        return ChatBlob("Points presets", self.build_preset_list())

    def build_preset_list(self):
        presets = self.db.query(
            "SELECT * FROM points_presets ORDER BY name ASC, points DESC")

        if presets:
            blob = ""

            for preset in presets:
                add_points_link = self.text.make_chatcmd(
                    "Add pts", "/tell <myname> raid addpts %s" % preset.name)
                delete_link = self.text.make_chatcmd(
                    "Delete",
                    "/tell <myname> presets rem %d" % preset.preset_id)
                blob += "<highlight>%s<end> worth <green>%d<end> points [id: %d]\n | [%s] [%s]\n\n" \
                        % (preset.name, preset.points, preset.preset_id, add_points_link, delete_link)

            return blob

        return "No presets available. To add new presets use <highlight><symbol>presets add preset_name preset_points<end>."

    def add_log_entry(self,
                      char_id: int,
                      leader_id: int,
                      reason: str,
                      amount=0):
        sql = "INSERT INTO points_log (char_id, audit, leader_id, reason, time) VALUES (?,?,?,?,?)"
        return self.db.exec(
            sql, [char_id, amount, leader_id, reason,
                  int(time.time())]) > 0

    def alter_points(self, current_points: int, char_id: int, amount: int,
                     leader_id: int, reason: str):
        sql = "UPDATE points SET points = points + ? WHERE char_id = ?"
        if self.db.exec(sql, [amount, char_id]) < 1:
            return False

        if not self.add_log_entry(char_id, leader_id, reason, amount):
            sql = "UPDATE points p SET p.points = ? WHERE p.char_id = ?"
            self.db.exec(sql, [current_points, char_id])
            return False

        return True

    def get_account(self, main_id):
        sql = "SELECT p.char_id, p.points, p.disabled FROM points p WHERE p.char_id = ?"
        return self.db.query_single(sql, [main_id])

    def get_account_display(self, char: SenderObj):
        main = self.alts_service.get_main(char.char_id)
        if not main:
            return "Could not find character <highlight>%s<end>." % char.name

        points_log = self.db.query(
            "SELECT * FROM points_log WHERE char_id = ? ORDER BY time DESC LIMIT 50",
            [main.char_id])
        points = self.db.query_single(
            "SELECT points, disabled FROM points WHERE char_id = ?",
            [main.char_id])
        if not points:
            return "Could not find raid account for <highlight>%s<end>." % char.name

        alts_link = self.text.make_chatcmd(
            "Alts", "/tell <myname> alts %s" % main.name)
        blob = ""
        blob += "Holder of account: %s [%s]\n" % (main.name, alts_link)
        blob += "Points: %d\n" % points.points
        blob += "Status: %s\n\n" % ("<green>Open<end>" if points.disabled == 0
                                    else "<red>Disabled<end>")

        blob += "<header2>Account log<end>\n"
        if points_log is None:
            blob += "No entries in log."
        else:
            for entry in points_log:
                name_reference = "<highlight>%s<end>" % char.name

                if entry.audit == 0:
                    # If points is 0, then it's a general case log
                    blob += "<grey>[%s]<end> <orange>\"%s\"<end>" % (
                        self.util.format_datetime(entry.time), entry.reason)
                elif entry.audit > 0:
                    pts = "<green>%d<end>" % entry.audit
                    blob += "<grey>[%s]<end> %s points were added to %s account " \
                            "by <highlight>%s<end> with reason <orange>%s<end>" \
                            % (self.util.format_datetime(entry.time),
                               pts, name_reference,
                               self.character_service.resolve_char_to_name(entry.leader_id), entry.reason)
                elif entry.audit < 0:
                    pts = "<red>%d<end>" % (-1 * entry.audit)
                    blob += "<grey>[%s]<end> %s points were taken from %s account " \
                            "by <highlight>%s<end> with reason <orange>%s<end>" \
                            % (self.util.format_datetime(entry.time),
                               pts, name_reference,
                               self.character_service.resolve_char_to_name(entry.leader_id),
                               entry.reason)

                log_entry_link = self.text.make_chatcmd(
                    "%d" % entry.log_id,
                    "/tell <myname> account logentry %d" % entry.log_id)
                blob += " [%s]\n" % log_entry_link

        return ChatBlob("%s Account" % char.name, blob)
コード例 #25
0
ファイル: tower_controller.py プロジェクト: Budabot/Tyrbot
class TowerController:
    def __init__(self):
        self.logger = Logger(__name__)

    def inject(self, registry):
        self.bot: Tyrbot = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util = registry.get_instance("util")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.setting_service = registry.get_instance("setting_service")
        self.playfield_controller: PlayfieldController = registry.get_instance(
            "playfield_controller")
        self.level_controller = registry.get_instance("level_controller")

    def pre_start(self):
        self.db.load_sql_file(self.module_dir + "/" + "tower_site.sql")
        self.db.load_sql_file(self.module_dir + "/" + "tower_site_bounds.sql")

    def start(self):
        self.command_alias_service.add_alias("hot", "lc open")

        self.setting_service.register(
            self.module_name, "tower_api_address",
            "https://tower-api.jkbff.com/v1/api/towers",
            TextSettingType(["https://tower-api.jkbff.com/v1/api/towers"]),
            "The address of the Tower API")
        self.setting_service.register(self.module_name,
                                      "tower_api_custom_headers", "",
                                      DictionarySettingType(),
                                      "Custom headers for the Tower API")

    @command(command="lc",
             params=[],
             access_level="guest",
             description=
             "See a list of playfields containing land control tower sites")
    def lc_list_cmd(self, request):
        data = self.db.query(
            "SELECT id, long_name, short_name FROM playfields WHERE id IN (SELECT DISTINCT playfield_id FROM tower_site) ORDER BY short_name"
        )

        blob = ""
        for row in data:
            blob += "[%d] %s <highlight>%s</highlight>\n" % (
                row.id,
                self.text.make_tellcmd(
                    row.long_name, "lc %s" % row.short_name), row.short_name)

        blob += "\n" + self.get_lc_blob_footer()

        return ChatBlob("Land Control Playfields (%d)" % len(data), blob)

    if FeatureFlags.USE_TOWER_API:

        @command(command="lc",
                 params=[Const("org"),
                         Any("org", is_optional=True)],
                 access_level="guest",
                 description="See a list of land control tower sites by org")
        def lc_org_cmd(self, request, _, org):
            params = list()
            params.append(("enabled", "true"))
            if not org:
                org = str(request.conn.org_id)
                if not org:
                    return "Bot does not belong to an org so an org name or org id must be specified."

            if org.isdigit():
                params.append(("org_id", org))
            else:
                for org_name_piece in org.split(" "):
                    params.append(("org_name", "%" + org_name_piece + "%"))

            data = self.lookup_tower_info(params).results

            t = int(time.time())
            grouped_data = self.util.group_by(data, lambda x:
                                              (x.org_id, x.org_name))
            blob = ""
            for k, v in grouped_data.items():
                v = sorted(v, key=lambda x: x.ql)

                org_blob = ""
                ct_types = []
                ql_total = 0
                for ct in v:
                    ct_types.append(self.get_ct_type(ct.ql))
                    ql_total += ct.ql
                    org_blob += self.format_site_info(ct, t) + "\n"

                blob += f"<pagebreak><header2>{k[1]} ({k[0]})</header2>"
                blob += " Types: <highlight>" + ", ".join(
                    ct_types
                ) + f"</highlight> Total CT QL: <highlight>{ql_total}</highlight>\n\n"
                blob += org_blob + "\n"

            return ChatBlob(f"Org Info for '{org}' ({len(data)})", blob)

        @command(
            command="lc",
            params=[
                Options([
                    "all", "open", "closed", "penalty", "unplanted", "disabled"
                ]),
                Options(["omni", "clan", "neutral", "all"], is_optional=True),
                Int("pvp_level", is_optional=True),
                Time("time", is_optional=True)
            ],
            access_level="guest",
            description=
            "See a list of land control tower sites by QL, faction, and open status",
            extended_description=
            "The time param only applies when the first param is either 'open' or 'closed'"
        )
        def lc_search_cmd(self, request, site_status, faction, pvp_level,
                          time_offset):
            t = int(time.time())
            relative_time = t + (time_offset or 0)

            min_ql = 1
            max_ql = 300
            if pvp_level:
                level_info = self.level_controller.get_level_info(pvp_level)
                if not level_info:
                    return "PVP level must be between 1 and 220."
                min_ql = level_info.pvp_min
                max_ql = level_info.pvp_max

            params = list()

            if site_status.lower() == "disabled":
                params.append(("enabled", "false"))
            else:
                params.append(("enabled", "true"))

            if min_ql > 1:
                params.append(("min_ql", min_ql))

            if max_ql < 300:
                params.append(("max_ql", max_ql))

            if faction and faction != "all":
                params.append(("faction", faction))

            if site_status.lower() == "open":
                params.append(("min_close_time", relative_time))
                params.append(("max_close_time", relative_time + (3600 * 6)))
            elif site_status.lower() == "closed":
                params.append(("min_close_time", relative_time + (3600 * 6)))
                params.append(("max_close_time", relative_time + (3600 * 24)))
            elif site_status.lower() == "penalty":
                params.append(("penalty", "true"))
            elif site_status.lower() == "unplanted":
                params.append(("planted", "false"))

            data = self.lookup_tower_info(params).results

            blob = ""
            for row in data:
                blob += "<pagebreak>" + self.format_site_info(row, t) + "\n"

            if blob:
                blob += self.get_lc_blob_footer()

            title = "Tower Info: %s" % site_status.capitalize()
            if min_ql > 1 or max_ql < 300:
                title += " QL %d - %d" % (min_ql, max_ql)
            if faction:
                title += " [%s]" % faction.capitalize()
            if time_offset:
                title += " in " + self.util.time_to_readable(time_offset)
            title += " (%d)" % len(data)

            return ChatBlob(title, blob)

    @command(command="lc",
             params=[Any("playfield"),
                     Int("site_number", is_optional=True)],
             access_level="guest",
             description=
             "See a list of land control tower sites in a particular playfield"
             )
    def lc_playfield_cmd(self, request, playfield_name, site_number):
        playfield = self.playfield_controller.get_playfield_by_name_or_id(
            playfield_name)
        if not playfield:
            return f"Could not find playfield <highlight>{playfield_name}</highlight>."

        data = self.get_tower_site_info(playfield.id, site_number)

        blob = ""
        t = int(time.time())
        for row in data:
            blob += "<pagebreak>" + self.format_site_info(row, t) + "\n"

        blob += self.get_lc_blob_footer()

        if site_number:
            title = "Tower Info: %s %d" % (playfield.long_name, site_number)
        else:
            title = "Tower Info: %s (%d)" % (playfield.long_name, len(data))

        return ChatBlob(title, blob)

    def format_site_info(self, row, t):
        blob = "<highlight>%s %d</highlight> (QL %d-%d) %s\n" % (
            row.playfield_short_name, row.site_number, row.min_ql, row.max_ql,
            row.site_name)

        if row.get("org_name"):
            current_day_time = t % 86400
            value = datetime.fromtimestamp(row.close_time, tz=pytz.UTC)
            current_status_time = row.close_time - current_day_time
            if current_status_time < 0:
                current_status_time += 86400

            status = ""
            if current_status_time <= 3600:
                status += "<red>5%%</red> (closes in %s)" % self.util.time_to_readable(
                    current_status_time)
            elif current_status_time <= (3600 * 6):
                status += "<orange>25%%</orange> (closes in %s)" % self.util.time_to_readable(
                    current_status_time)
            else:
                status += "<green>75%%</green> (opens in %s)" % self.util.time_to_readable(
                    current_status_time - (3600 * 6))

            if row.penalty_until > t:
                status += " <red>Penalty</red> (for %s)" % self.util.time_to_readable(
                    row.penalty_until - t)

            blob += "%s (%d) [%s] <highlight>QL %d</highlight> %s %s\n" % (
                row.org_name, row.org_id,
                self.text.get_formatted_faction(row.faction), row.ql,
                self.text.make_chatcmd(
                    "%dx%d" %
                    (row.x_coord, row.y_coord), "/waypoint %d %d %d" %
                    (row.x_coord, row.y_coord, row.playfield_id)),
                self.util.time_to_readable(t - row.created_at))
            blob += "Close Time: <highlight>%s</highlight> %s\n" % (
                value.strftime("%H:%M:%S %Z"), status)
        else:
            blob += "%s\n" % self.text.make_chatcmd(
                "%dx%d" % (row.x_coord, row.y_coord), "/waypoint %d %d %d" %
                (row.x_coord, row.y_coord, row.playfield_id))
            if not row.enabled:
                blob += "<red>Disabled</red>\n"

        return blob

    def get_tower_site_info(self, playfield_id, site_number):
        if FeatureFlags.USE_TOWER_API:
            params = list()
            params.append(("playfield_id", playfield_id))
            if site_number:
                params.append(("site_number", site_number))

            data = self.lookup_tower_info(params).results
        else:
            if site_number:
                data = self.db.query(
                    "SELECT t.*, p.short_name AS playfield_short_name, p.long_name AS playfield_long_name "
                    "FROM tower_site t JOIN playfields p ON t.playfield_id = p.id WHERE t.playfield_id = ? AND site_number = ?",
                    [playfield_id, site_number])
            else:
                data = self.db.query(
                    "SELECT t.*, p.short_name AS playfield_short_name, p.long_name AS playfield_long_name "
                    "FROM tower_site t JOIN playfields p ON t.playfield_id = p.id WHERE t.playfield_id = ?",
                    [playfield_id])

        return data

    def lookup_tower_info(self, params):
        url = self.setting_service.get("tower_api_address").get_value()

        headers = self.setting_service.get(
            "tower_api_custom_headers").get_value() or {}
        headers.update({"User-Agent": f"Tyrbot {self.bot.version}"})
        r = requests.get(url, params, headers=headers, timeout=5)
        result = DictObject(r.json())

        return result

    def get_lc_blob_footer(self):
        return "Thanks to Draex and Unk for providing the tower information. And a special thanks to Trey."

    def get_ct_type(self, ql):
        if ql < 34:
            return "I"
        elif ql < 82:
            return "II"
        elif ql < 129:
            return "III"
        elif ql < 177:
            return "IV"
        elif ql < 201:
            return "V"
        elif ql < 226:
            return "VI"
        else:
            return "VII"
コード例 #26
0
class AdminController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.admin_service = registry.get_instance("admin_service")
        self.pork_service = registry.get_instance("pork_service")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.buddy_service = registry.get_instance("buddy_service")

    def start(self):
        self.command_alias_service.add_alias("adminlist", "admin")
        self.command_alias_service.add_alias("admins", "admin")

    @command(command="admin",
             params=[],
             access_level="all",
             description="Show the admin list")
    def admin_list_cmd(self, request):
        admins = self.admin_service.get_all()

        blob = ""
        current_access_level = ""
        for row in admins:
            if row.access_level != current_access_level:
                blob += "\n<header2>%s</header2>\n" % row.access_level.capitalize(
                )
                current_access_level = row.access_level

            if row.name:
                blob += row.name
            else:
                blob += "Unknown(%d)" % row.char_id

            if self.buddy_service.is_online(row.char_id):
                blob += " [<green>Online</green>]"
            blob += "\n"

        return ChatBlob("Admin List (%d)" % len(admins), blob)

    @command(command="admin",
             params=[Const("add"), Character("character")],
             access_level="superadmin",
             description="Add an admin",
             sub_command="modify")
    def admin_add_cmd(self, request, _, char):
        if not char.char_id:
            return StandardMessage.char_not_found(char.name)

        if self.admin_service.add(char.char_id, AdminService.ADMIN):
            return f"Character <highlight>{char.name}</highlight> added as <highlight>{AdminService.ADMIN}</highlight> successfully."
        else:
            return f"Could not add character <highlight>{char.name}</highlight> as <highlight>{AdminService.ADMIN}</highlight>."

    @command(command="admin",
             params=[Options(["remove", "rem"]),
                     Character("character")],
             access_level="superadmin",
             description="Remove an admin",
             sub_command="modify")
    def admin_remove_cmd(self, request, _, char):
        if not char.char_id:
            return StandardMessage.char_not_found(char.name)

        if self.admin_service.remove(char.char_id):
            return f"Character <highlight>{char.name}</highlight> removed as <highlight>{AdminService.ADMIN}</highlight> successfully."
        else:
            return f"Could not remove character <highlight>{char.name}</highlight> as <highlight>{AdminService.ADMIN}</highlight>."

    @command(command="moderator",
             params=[Const("add"), Character("character")],
             access_level="admin",
             description="Add a moderator",
             sub_command="modify")
    def moderator_add_cmd(self, request, _, char):
        if not char.char_id:
            return StandardMessage.char_not_found(char.name)

        if self.admin_service.add(char.char_id, AdminService.MODERATOR):
            return f"Character <highlight>{char.name}</highlight> added as <highlight>{AdminService.MODERATOR}</highlight> successfully."
        else:
            return f"Could not add character <highlight>{char.name}</highlight> as <highlight>{AdminService.MODERATOR}</highlight>."

    @command(command="moderator",
             params=[Options(["remove", "rem"]),
                     Character("character")],
             access_level="admin",
             description="Remove a moderator",
             sub_command="modify")
    def moderator_remove_cmd(self, request, _, char):
        if not char.char_id:
            return StandardMessage.char_not_found(char.name)

        if self.admin_service.remove(char.char_id):
            return f"Character <highlight>{char.name}</highlight> removed as <highlight>{AdminService.MODERATOR}</highlight> successfully."
        else:
            return f"Could not remove character <highlight>{char.name}</highlight> as <highlight>{AdminService.MODERATOR}</highlight>."

    @event(event_type="connect",
           description="Add admins as buddies",
           is_system=True)
    def connect_event(self, event_type, event_data):
        for row in self.admin_service.get_all():
            self.buddy_service.add_buddy(row.char_id, "admin")
コード例 #27
0
ファイル: topic_controller.py プロジェクト: fatpower/Tyrbot-1
class TopicController:
    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util = registry.get_instance("util")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.private_channel_service: PrivateChannelService = registry.get_instance(
            "private_channel_service")

    def start(self):
        self.command_alias_service.add_alias("motd", "topic")

    @setting(name="topic", value="", description="The bot topic")
    def topic(self):
        return DictionarySettingType()

    @command(command="topic",
             params=[],
             access_level="all",
             description="Show the current topic")
    def topic_show_command(self, request):
        topic = self.topic().get_value()
        if topic:
            return self.format_topic_message(topic)
        else:
            return "There is no current topic."

    @command(command="topic",
             params=[Options(["clear", "unset"])],
             access_level="all",
             description="Clears the current topic")
    def topic_clear_command(self, request, _):
        self.topic().set_value("")

        return "The topic has been cleared."

    @command(command="topic",
             params=[Const("set", is_optional=True),
                     Any("topic_message")],
             access_level="all",
             description="Set the current topic")
    def topic_set_command(self, request, _, topic_message):
        sender = DictObject({
            "name": request.sender.name,
            "char_id": request.sender.char_id
        })

        topic = {
            "topic_message": topic_message,
            "created_by": sender,
            "created_at": int(time.time())
        }

        self.topic().set_value(topic)

        return "The topic has been set."

    def format_topic_message(self, topic):
        time_string = self.util.time_to_readable(
            int(time.time()) - topic["created_at"])
        return "Topic: <highlight>%s<end> [set by <highlight>%s<end>][%s ago]" % (
            topic["topic_message"], topic["created_by"]["name"], time_string)

    @event(PrivateChannelService.JOINED_PRIVATE_CHANNEL_EVENT,
           "Show topic to characters joining the private channel")
    def show_topic(self, _, event_data):
        topic = self.topic().get_value()
        if topic:
            self.bot.send_private_message(event_data.char_id,
                                          self.format_topic_message(topic))

    @event(PrivateChannelService.LEFT_PRIVATE_CHANNEL_EVENT,
           "Clear topic when there are no characters in the private channel")
    def clear_topic(self, _, event_data):
        if self.topic().get_value() and len(self.private_channel_service.
                                            get_all_in_private_channel()) == 0:
            self.topic().set_value("")
コード例 #28
0
class AdminController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.admin_service = registry.get_instance("admin_service")
        self.pork_service = registry.get_instance("pork_service")
        self.command_alias_service = registry.get_instance(
            "command_alias_service")
        self.buddy_service = registry.get_instance("buddy_service")

    def start(self):
        self.command_alias_service.add_alias("adminlist", "admin")
        self.command_alias_service.add_alias("admins", "admin")

    @command(command="admin",
             params=[],
             access_level="all",
             description="Show the admin list")
    def admin_list_cmd(self, request):
        admins = self.admin_service.get_all()

        blob = ""
        current_access_level = ""
        for row in admins:
            if row.access_level != current_access_level:
                blob += "\n<header2>%s<end>\n" % row.access_level.capitalize()
                current_access_level = row.access_level

            blob += row.name
            if self.buddy_service.is_online(row.char_id):
                blob += " [<green>Online<end>]"
            blob += "\n"

        return ChatBlob("Admin List (%d)" % len(admins), blob)

    @command(command="admin",
             params=[Const("add"), Character("character")],
             access_level="superadmin",
             description="Add an admin",
             sub_command="modify")
    def admin_add_cmd(self, request, _, char):
        if not char.char_id:
            return "Could not find character <highlight>%s<end>." % char.name

        if self.admin_service.add(char.char_id, AdminService.ADMIN):
            return "Character <highlight>%s<end> added as <highlight>%s<end> successfully." % (
                char.name, AdminService.ADMIN)
        else:
            return "Could not add character <highlight>%s<end> as <highlight>%s<end>." % (
                char.name, AdminService.ADMIN)

    @command(command="admin",
             params=[Options(["remove", "rem"]),
                     Character("character")],
             access_level="superadmin",
             description="Remove an admin",
             sub_command="modify")
    def admin_remove_cmd(self, request, _, char):
        if not char.char_id:
            return "Could not find character <highlight>%s<end>." % char.name

        if self.admin_service.remove(char.char_id):
            return "Character <highlight>%s<end> removed as <highlight>%s<end> successfully." % (
                char.name, AdminService.ADMIN)
        else:
            return "Could not remove character <highlight>%s<end> as <highlight>%s<end>." % (
                char.name, AdminService.ADMIN)

    @command(command="moderator",
             params=[Const("add"), Character("character")],
             access_level="admin",
             description="Add a moderator",
             sub_command="modify")
    def moderator_add_cmd(self, request, _, char):
        if not char.char_id:
            return "Could not find character <highlight>%s<end>." % char.name

        if self.admin_service.add(char.char_id, AdminService.MODERATOR):
            return "Character <highlight>%s<end> added as <highlight>%s<end> successfully." % (
                char.name, AdminService.MODERATOR)
        else:
            return "Could not add character <highlight>%s<end> as <highlight>%s<end>." % (
                char.name, AdminService.MODERATOR)

    @command(command="moderator",
             params=[Options(["remove", "rem"]),
                     Character("character")],
             access_level="admin",
             description="Remove a moderator",
             sub_command="modify")
    def moderator_remove_cmd(self, request, _, char):
        if not char.char_id:
            return "Could not find character <highlight>%s<end>." % char.name

        if self.admin_service.remove(char.char_id):
            return "Character <highlight>%s<end> removed as <highlight>%s<end> successfully." % (
                char.name, AdminService.MODERATOR)
        else:
            return "Could not remove character <highlight>%s<end> as <highlight>%s<end>." % (
                char.name, AdminService.MODERATOR)
コード例 #29
0
class AdminController:
    def __init__(self):
        pass

    def inject(self, registry):
        self.bot = registry.get_instance("bot")
        self.admin_manager = registry.get_instance("admin_manager")
        self.character_manager = registry.get_instance("character_manager")
        self.pork_manager = registry.get_instance("pork_manager")

    @command(command="admin",
             params=[],
             access_level="all",
             description="Show the admin list")
    def admin_list_cmd(self, channel, sender, reply, args):
        admins = self.admin_manager.get_all()
        superadmin = self.pork_manager.get_character_info(self.bot.superadmin)
        superadmin.access_level = "superadmin"
        admins.insert(0, superadmin)

        blob = ""
        current_access_level = ""
        for row in admins:
            if row.access_level != current_access_level:
                blob += "\n<header2>%s<end>\n" % row.access_level.capitalize()
                current_access_level = row.access_level

            blob += row.name + "\n"

        reply(ChatBlob("Admin List (%d)" % len(admins), blob))

    @command(command="admin",
             params=[Const("add"), Any("character")],
             access_level="superadmin",
             description="Add an admin",
             sub_command="modify")
    def admin_add_cmd(self, channel, sender, reply, args):
        name = args[1].capitalize()
        char_id = self.character_manager.resolve_char_to_id(name)

        if not char_id:
            reply("Could not find character <highlight>%s<end>." % name)
            return

        if self.admin_manager.add(char_id, AdminManager.ADMIN):
            reply(
                "Character <highlight>%s<end> added as <highlight>%s<end> successfully."
                % (name, AdminManager.ADMIN))
        else:
            reply(
                "Could not add character <highlight>%s<end> as <highlight>%s<end>."
                % (name, AdminManager.ADMIN))

    @command(command="admin",
             params=[Options(["remove", "rem"]),
                     Any("character")],
             access_level="superadmin",
             description="Remove an admin",
             sub_command="modify")
    def admin_remove_cmd(self, channel, sender, reply, args):
        name = args[1].capitalize()
        char_id = self.character_manager.resolve_char_to_id(name)

        if not char_id:
            reply("Could not find character <highlight>%s<end>." % name)
            return

        if self.admin_manager.remove(char_id):
            reply(
                "Character <highlight>%s<end> removed as <highlight>%s<end> successfully."
                % (name, AdminManager.ADMIN))
        else:
            reply(
                "Could not remove character <highlight>%s<end> as <highlight>%s<end>."
                % (name, AdminManager.ADMIN))

    @command(command="moderator",
             params=[Const("add"), Any("character")],
             access_level="superadmin",
             description="Add a moderator",
             sub_command="modify")
    def moderator_add_cmd(self, channel, sender, reply, args):
        name = args[1].capitalize()
        char_id = self.character_manager.resolve_char_to_id(name)

        if not char_id:
            reply("Could not find character <highlight>%s<end>." % name)
            return

        if self.admin_manager.add(char_id, AdminManager.MODERATOR):
            reply(
                "Character <highlight>%s<end> added as <highlight>%s<end> successfully."
                % (name, AdminManager.MODERATOR))
        else:
            reply(
                "Could not add character <highlight>%s<end> as <highlight>%s<end>."
                % (name, AdminManager.MODERATOR))

    @command(command="moderator",
             params=[Options(["remove", "rem"]),
                     Any("character")],
             access_level="superadmin",
             description="Remove a moderator",
             sub_command="modify")
    def moderator_remove_cmd(self, channel, sender, reply, args):
        name = args[1].capitalize()
        char_id = self.character_manager.resolve_char_to_id(name)

        if not char_id:
            reply("Could not find character <highlight>%s<end>." % name)
            return

        if self.admin_manager.remove(char_id):
            reply(
                "Character <highlight>%s<end> removed as <highlight>%s<end> successfully."
                % (name, AdminManager.MODERATOR))
        else:
            reply(
                "Could not remove character <highlight>%s<end> as <highlight>%s<end>."
                % (name, AdminManager.MODERATOR))
コード例 #30
0
ファイル: quote_controller.py プロジェクト: Budabot/Tyrbot
class QuoteController:
    def inject(self, registry):
        self.db: DB = registry.get_instance("db")
        self.text: Text = registry.get_instance("text")
        self.util = registry.get_instance("util")

    def start(self):
        self.db.exec(
            "CREATE TABLE IF NOT EXISTS quote (id INT PRIMARY KEY AUTO_INCREMENT, char_id INT NOT NULL, created_at INT NOT NULL, content VARCHAR(4096) NOT NULL)"
        )

    @command(command="quote",
             params=[],
             access_level="guest",
             description="Show a random quote")
    def quote_command(self, request):
        quote = self.get_random_quote()

        if quote:
            return self.format_quote(quote, request.conn)
        else:
            return "There are no quotes to display."

    @command(command="quote",
             params=[Int("quote_id")],
             access_level="guest",
             description="Show a specific quote")
    def quote_view_command(self, request, quote_id):
        quote = self.get_quote_info(quote_id)

        if quote:
            return self.format_quote(quote, request.conn)
        else:
            return "Quote with ID <highlight>%d</highlight> does not exist." % quote_id

    @command(command="quote",
             params=[Const("add"), Any("quote")],
             access_level="guest",
             description="Show a specific quote")
    def quote_add_command(self, request, _, quote):
        if len(quote) > 4096:
            return "Your quote must be less than 4096 characters."

        next_id = self.db.query_single(
            "SELECT (COALESCE(MAX(id), 0) + 1) AS next_id FROM quote").next_id
        self.db.exec(
            "INSERT INTO quote (id, char_id, created_at, content) VALUES (?, ?, ?, ?)",
            [next_id, request.sender.char_id,
             int(time.time()), quote])

        return f"Quote with ID <highlight>{next_id}</highlight> has been added successfully."

    @command(command="quote",
             params=[Options(["rem", "remove"]),
                     Int("quote_id")],
             access_level="moderator",
             description="Remove a quote",
             sub_command="remove")
    def quote_remove_command(self, request, _, quote_id):
        num_rows = self.db.exec("DELETE FROM quote WHERE id = ?", [quote_id])

        if num_rows:
            return f"Quote with ID <highlight>{quote_id}</highlight> has been removed successfully."
        else:
            return "Quote with ID <highlight>%d</highlight> does not exist." % quote_id

    @command(command="quote",
             params=[Const("search"), Any("search_params")],
             access_level="guest",
             description="Search for a quote")
    def quote_search_command(self, request, _, search_params):
        sql = "SELECT q.*, p.name FROM quote q LEFT JOIN player p ON q.char_id = p.char_id " \
              "WHERE q.content <EXTENDED_LIKE=0> ? OR p.name LIKE ? " \
              "ORDER BY q.id ASC"
        data = self.db.query(sql, [search_params, search_params],
                             extended_like=True)

        blob = ""
        for row in data:
            blob += self.text.make_tellcmd(row.id, f"quote {row.id}")
            blob += " "
            blob += row.content
            blob += "\n\n"

        return ChatBlob("Quote Search Results (%d)" % len(data), blob)

    def get_random_quote(self):
        quotes = self.db.query(
            "SELECT q.*, p.name FROM quote q LEFT JOIN player p ON q.char_id = p.char_id ORDER BY q.id ASC"
        )
        if quotes:
            return random.choice(quotes)
        else:
            return None

    def get_quote_info(self, quote_id):
        return self.db.query_single(
            "SELECT q.*, p.name FROM quote q LEFT JOIN player p ON q.char_id = p.char_id WHERE q.id = ?",
            [quote_id])

    def format_quote(self, quote, conn):
        blob = f"ID: <highlight>{quote.id}</highlight>\n"
        blob += f"Created By: <highlight>{quote.name or quote.char_id}</highlight>\n"
        blob += f"Created At: <highlight>{self.util.format_datetime(quote.created_at)}</highlight>\n\n"
        blob += quote.content

        chat_blob = ChatBlob("More Info", blob)
        more_info_link = self.text.paginate(chat_blob, conn)[0]
        return "%d. %s %s" % (quote.id, quote.content, more_info_link)