From bf6c1842d2accf99d6879a238c662d97ab72f453 Mon Sep 17 00:00:00 2001 From: Minidodo Date: Tue, 30 Nov 2021 16:57:31 +0100 Subject: [PATCH] Do not load settings which are not active (module not loaded) Restart the bot, on heavy DB errors, with an 30 seconds delay (like: all connections terminated by DB, table_definition_cache exhausted) Fix for channel prefixing (org <-> priv) --- bootstrap.py | 3 +-- core/buddy_service.py | 3 +-- core/db.py | 8 ++++++++ core/igncore.py | 2 +- core/public_channel_service.py | 4 ++-- core/registry.py | 9 +++++++-- core/setting_service.py | 4 ++++ core/text.py | 4 ++-- modules/core/accounting/account_controller.py | 2 +- modules/core/accounting/alts_controller.py | 3 ++- .../core/private_channel/private_channel_controller.py | 10 +++++----- modules/orgbot/org/cloak_controller.py | 4 ++-- modules/orgbot/org/org_controller.py | 10 +++++----- modules/orgbot/org/org_roster_controller.py | 2 ++ modules/standard/loot/loot_controller.py | 4 ++-- modules/standard/raid/chat_controller.py | 10 ++++++++++ modules/standard/specials/specials_controller.py | 4 ++-- 17 files changed, 57 insertions(+), 29 deletions(-) diff --git a/bootstrap.py b/bootstrap.py index 690994a..fceaed2 100644 --- a/bootstrap.py +++ b/bootstrap.py @@ -77,11 +77,10 @@ try: # paths to search for instances: core + module_paths paths = ["core"] paths.extend(config.module_paths) - # load instances logger.debug("Loading instances") Registry.load_instances(paths) - Registry.inject_all() + Registry.inject_all(paths) # configure database db = Registry.get_instance("db") diff --git a/core/buddy_service.py b/core/buddy_service.py index 2c3f3eb..f79675f 100644 --- a/core/buddy_service.py +++ b/core/buddy_service.py @@ -36,8 +36,7 @@ class BuddyService: # verify that buddy does not exist on any other conn for conn_id, conn_buddy_list in self.buddy_list.items(): if conn.id != conn_id: - buddy = conn_buddy_list.get(packet.char_id, None) - if buddy: + if buddy := conn_buddy_list.get(packet.char_id, None): if buddy["online"] is None: # remove from other conn list del conn_buddy_list[packet.char_id] diff --git a/core/db.py b/core/db.py index 2d61033..677b9b9 100644 --- a/core/db.py +++ b/core/db.py @@ -76,6 +76,14 @@ class DB: except Exception as e: raise SqlException(f"SQL Error: '{str(e)}' for '{sql}' " f"[{', '.join(map(lambda x: str(x), params))}]") from e + except mariadb.OperationalError as e: + self.logger.error("Please use 'FLUSH TABLES;' inside of the DB, and consider upping the 'table_definition_cache' value of the Database Server.", e) + time.sleep(30) + exit(-3) + except mariadb.PoolError as e: + self.logger.error("No Connections available for the Connection Pool. Restarting in 30 seconds...", e) + time.sleep(30) + exit(-2) elapsed = time.time() - start_time result = callback(cur) if elapsed > 5: diff --git a/core/igncore.py b/core/igncore.py index f8cb2bc..fbf0d5f 100644 --- a/core/igncore.py +++ b/core/igncore.py @@ -43,7 +43,7 @@ class IgnCore: self.last_timer_event = 0 self.start_time = int(time.time()) self.major_version = "IGNCore v2.8" - self.minor_version = "0" + self.minor_version = "1" self.incoming_queue = FifoQueue() self.mass_message_queue = None self.conns = DictObject() diff --git a/core/public_channel_service.py b/core/public_channel_service.py index 3e9a6ad..c594251 100644 --- a/core/public_channel_service.py +++ b/core/public_channel_service.py @@ -87,7 +87,7 @@ class PublicChannelService(BaseModule): return if self.is_org_channel_id(packet.channel_id): - if self.setting_service.get_value("log_org") == "1" and packet.char_id == self.bot.get_char_id(): + if self.setting_service.get_value("log_org") == "1": char_name = self.character_service.get_char_name(packet.char_id) if packet.extended_message: message = packet.extended_message.get_message() @@ -96,7 +96,7 @@ class PublicChannelService(BaseModule): self.logger.log_chat(conn.id, "Org Channel", char_name, message) self.event_service.fire_event(self.ORG_CHANNEL_MESSAGE_EVENT, packet) elif packet.channel_id == self.ORG_MSG_CHANNEL_ID: - if self.setting_service.get_value("log_org") == "1" and packet.char_id == self.bot.get_char_id(): + if self.setting_service.get_value("log_org") == "1": char_name = self.character_service.get_char_name(packet.char_id) if packet.extended_message: message = packet.extended_message.get_message() diff --git a/core/registry.py b/core/registry.py index a08aa46..cd8f9c3 100644 --- a/core/registry.py +++ b/core/registry.py @@ -10,7 +10,7 @@ class Registry: logger = None @classmethod - def inject_all(cls): + def inject_all(cls, modules): # inject registry so instance can get references to other instances for key in cls._registry: try: @@ -23,7 +23,10 @@ class Registry: @classmethod def pre_start_all(cls): # call pre_start() on instances so they can start any init() processes + mods = cls.get_instance("bot").modules for key in cls._registry: + if str(cls._registry[key].module_name).split(".")[0] not in mods: + continue try: cls._registry[key].pre_start except AttributeError: @@ -34,7 +37,10 @@ class Registry: @classmethod def start_all(cls): # call start() on instances so they can finish any init() processes + mods = cls.get_instance("bot").modules for key in cls._registry: + if str(cls._registry[key].module_name).split(".")[0] not in mods: + continue try: cls._registry[key].start except AttributeError: @@ -60,7 +66,6 @@ class Registry: inst.module_name = Registry.get_module_name(inst) inst.module_dir = Registry.get_module_dir(inst) - if not override and name in cls._registry: raise Exception("Overriding '%s' with new instance" % name) elif override and name not in cls._registry: diff --git a/core/setting_service.py b/core/setting_service.py index 56b1590..8b3dab2 100644 --- a/core/setting_service.py +++ b/core/setting_service.py @@ -24,6 +24,10 @@ class SettingService: for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "setting"): + key = Registry.get_module_name(inst).split(".") + # We dont want to load settings, if their modules not enabled in our config... + if key[0] not in self.bot.modules: + continue setting_name, value, description, extended_description, obj = getattr(method, "setting") self.register(inst.module_name, setting_name, value, obj, description, extended_description) diff --git a/core/text.py b/core/text.py index 27f501a..d94a948 100644 --- a/core/text.py +++ b/core/text.py @@ -53,7 +53,7 @@ class Text: def inject(self, registry): self.setting_service: SettingService = registry.get_instance("setting_service") - self.ban = registry.get_instance("ban_service") + self.ban = registry.get_instance("ban_service", is_optional=True) self.bot = registry.get_instance("bot") self.public_channel_service = registry.get_instance("public_channel_service") @@ -153,7 +153,7 @@ class Text: msg = f"{char_info.name}" else: msg = f"CharId({char_info.char_id:d})" - if check_ban: + if check_ban and self.ban: banned = f" :: Banned!" if self.ban.get_ban(char_info.char_id) else "" msg += banned if online_status is not None: diff --git a/modules/core/accounting/account_controller.py b/modules/core/accounting/account_controller.py index 05a29e0..e1d34c0 100644 --- a/modules/core/accounting/account_controller.py +++ b/modules/core/accounting/account_controller.py @@ -159,7 +159,7 @@ class AccountController: self.db.exec("DELETE FROM pending_accounts where main=? or alt=?", [account[0].main, account[0].main]) self.db.exec("DELETE FROM mail where recipient=? or sender=?", [account[0].main, account[0].main]) self.account_service.add_log(request.sender.char_id, "system", - f"Disabled Account of {user.name}.", + f"Purged the account of {user.name}.", request.sender.char_id) return f"Character {user.name}'s Account has been purged!" else: diff --git a/modules/core/accounting/alts_controller.py b/modules/core/accounting/alts_controller.py index f28adc9..29a179d 100644 --- a/modules/core/accounting/alts_controller.py +++ b/modules/core/accounting/alts_controller.py @@ -6,6 +6,7 @@ from core.chat_blob import ChatBlob from core.command_param_types import Const, Options, Character, Multiple, Any from core.decorators import instance, command from core.dict_object import DictObject +from core.sender_obj import SenderObj from core.setting_service import SettingService from core.text import Text from core.translation_service import TranslationService @@ -135,7 +136,7 @@ class AltsController: for alt in alts: char_id = self.character_service.resolve_char_to_id(alt) if not char_id: - notfound.append(alt) + notfound.append(alt.name if type(alt) == SenderObj else alt) continue alt = DictObject({"char_id": char_id, "name": alt}) if main.char_id == alt.char_id: diff --git a/modules/core/private_channel/private_channel_controller.py b/modules/core/private_channel/private_channel_controller.py index d96069f..1951d4b 100644 --- a/modules/core/private_channel/private_channel_controller.py +++ b/modules/core/private_channel/private_channel_controller.py @@ -78,7 +78,7 @@ class PrivateChannelController: return hjson.load(f) def handle_incoming_relay_message(self, ctx): - if not self.display_main().get_value() == "1" and ctx.source == "org_channel" and ctx.sender: + if self.display_main().get_value() and ctx.source == "private_channel" and ctx.sender: name = f"{OrgChannelController.ORG_CHANNEL_PREFIX} {ctx.sender.name}" if account := self.account_service.get_account(ctx.sender.char_id): if account.main != ctx.sender.char_id: @@ -92,9 +92,9 @@ class PrivateChannelController: if not self.bot.is_ready(): if data.packet.char_id not in self.reinvite: account = data.account - if account.disabled == 1: + if not self.account_service.simple_checks(account): return - if self.pork.get_character_info(data.packet.char_id).org_id == self.bot.public_channel_service.org_id: + if self.account_service.get_entry(data.packet.char_id).get("member", self.bot.public_channel_service.org_id) == self.bot.public_channel_service.org_id: return if account.auto_invite == 1: self.reinvite.append(data.packet.char_id) @@ -102,12 +102,12 @@ class PrivateChannelController: if self.private_channel_service.in_private_channel(data.packet.char_id): return account = data.account - if account.disabled == 1: + if not self.account_service.simple_checks(account): return if self.db.query_single("SELECT * from org_bots where char_id=?", [data.packet.char_id]): return if account.auto_invite == 1: - if self.pork.get_character_info(data.packet.char_id).org_id != self.bot.public_channel_service.org_id: + if self.account_service.get_entry(data.packet.char_id).get("member", self.bot.public_channel_service.org_id) != self.bot.public_channel_service.org_id: self.private_channel_service.invite(data.packet.char_id) self.bot.send_mass_message(data.packet.char_id, "You have been " "auto invited " diff --git a/modules/orgbot/org/cloak_controller.py b/modules/orgbot/org/cloak_controller.py index c926c30..c3f9131 100644 --- a/modules/orgbot/org/cloak_controller.py +++ b/modules/orgbot/org/cloak_controller.py @@ -86,8 +86,8 @@ class CloakController: timer_name = "Lower City Cloak" else: raise Exception(f"Unknown cloak action '{event_data.action}'") - - self.timer_controller.add_timer(timer_name, event_data.sender.char_id, "org", int(time.time()), 3600) + if self.timer_controller: + self.timer_controller.add_timer(timer_name, event_data.sender.char_id, "org", int(time.time()), 3600) def get_cloak_status(self, row): one_hour = 3600 diff --git a/modules/orgbot/org/org_controller.py b/modules/orgbot/org/org_controller.py index 0bed43b..34440ea 100644 --- a/modules/orgbot/org/org_controller.py +++ b/modules/orgbot/org/org_controller.py @@ -40,14 +40,14 @@ class OrgChannelController: def start(self): self.message_hub_service.register_message_destination( - self.MESSAGE_SOURCE, self.handle_incoming_relay_message, - ["private_channel", "websocket_relay", "cloak_reminder", "wave_counter", "shutdown_notice"], - [self.MESSAGE_SOURCE]) + self.MESSAGE_SOURCE, self.handle_incoming_relay_message, + ["private_channel", "websocket_relay", "cloak_reminder", "wave_counter", "shutdown_notice"], + [self.MESSAGE_SOURCE]) def handle_incoming_relay_message(self, ctx): # {'source': 'org_channel', 'sender': {'char_id': 384018, 'name': 'Risianna'}, 'message': 'Sooo', 'formatted_message': "[Org] Risianna: Sooo"} - if not self.display_main().get_value() == "1" and ctx.source == "private_channel" and ctx.sender: - name = f"{OrgChannelController.ORG_CHANNEL_PREFIX} {ctx.sender.name}" + if self.display_main().get_value() and ctx.source == "private_channel" and ctx.sender: + name = f"[Priv] {ctx.sender.name}" if account := self.account_service.get_account(ctx.sender.char_id): if account.main != ctx.sender.char_id: name += f" ({account.name})" diff --git a/modules/orgbot/org/org_roster_controller.py b/modules/orgbot/org/org_roster_controller.py index fdc5895..c710acc 100644 --- a/modules/orgbot/org/org_roster_controller.py +++ b/modules/orgbot/org/org_roster_controller.py @@ -217,6 +217,8 @@ class OrgRosterController: self.db.exec("INSERT INTO org_activity (message, time) VALUES(?, ?)", [ext_msg.get_message(), time.time()]) def process_org_msg(self, char_name, new_mode, actee=None): + # TODO: errors out on newly created chars, which do not show up on PoRK yet. + # self.pork.get_character_info(char_name) char_id = self.character_service.resolve_char_to_id(char_name) org_member = self.get_org_member(char_id) self.process_update(char_id, org_member.member if org_member else None, new_mode, actee) diff --git a/modules/standard/loot/loot_controller.py b/modules/standard/loot/loot_controller.py index 52ea7bb..09d26b8 100644 --- a/modules/standard/loot/loot_controller.py +++ b/modules/standard/loot/loot_controller.py @@ -356,9 +356,9 @@ class LootController: if int(time.time()) - self.last_modify > 3600 and self.loot_list: self.last_modify = None self.loot_list = OrderedDict() - self.bot.send_org_message("Loot was last modified more than 1 hour ago, list has been cleared.") + self.bot.send_org_message("Loot was last modified more than 1 hour ago, list has been cleared.", fire_outgoing_event=False) self.bot.send_private_channel_message( - "Loot was last modified more than 1 hour ago, list has been cleared.") + "Loot was last modified more than 1 hour ago, list has been cleared.", fire_outgoing_event=False) def is_already_added(self, name: str): for i, loot_item in self.loot_list.items(): diff --git a/modules/standard/raid/chat_controller.py b/modules/standard/raid/chat_controller.py index ff7ad83..e879e58 100644 --- a/modules/standard/raid/chat_controller.py +++ b/modules/standard/raid/chat_controller.py @@ -1,6 +1,7 @@ from core.command_param_types import Any from core.decorators import instance, command from core.igncore import IgnCore +from core.text import Text @instance() @@ -8,6 +9,7 @@ class ChatController: def inject(self, registry): self.command_alias_service = registry.get_instance("command_alias_service") self.bot: IgnCore = registry.get_instance("bot") + self.text: Text = registry.get_instance("text") def start(self): self.command_alias_service.add_alias("cmd", "shout") @@ -20,3 +22,11 @@ class ChatController: f"────────────────\n" f"{message}\n" f"────────────────") + + @command(command="lft", params=[Any("message", is_optional=True)], access_level="member", + description="Show a highly visible message") + def shout_command(self, _, message): + lft = f"'}'>/lft {message or ''}" + return self.text.format_page("Use this command for going LFT", "────────────────\n" + f"{lft}\n" + f"────────────────") diff --git a/modules/standard/specials/specials_controller.py b/modules/standard/specials/specials_controller.py index 03c54f6..ab003cf 100644 --- a/modules/standard/specials/specials_controller.py +++ b/modules/standard/specials/specials_controller.py @@ -390,9 +390,9 @@ class SpecialsController: inits_recharge = ((((init_result - 87.5) * 0.02) + 1 - weapon_attack + 4) * -900) + 1200 if inits_attack < inits_recharge: - return inits_recharge + return int(inits_recharge) else: - return inits_attack + return int(inits_attack) def get_aimed_shot_info(self, weapon_attack, weapon_recharge, aimed_shot_skill): result = DictObject()