From 6640d70440e3dc759f1f8745c427ef5b15a630a8 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 6 Nov 2022 22:17:17 +0100 Subject: [PATCH] Added logic to send message after level up #25 --- .../bot/config/appsettings.edrafts-pc.json | 7 +++- kdb-bot/src/bot/startup_settings_extension.py | 2 + .../src/bot_core/service/message_service.py | 9 ++++- .../configuration/default_level_settings.py | 39 +++++++++++++++++++ .../configuration/level_server_settings.py | 29 ++++++++++++++ .../level/configuration/level_settings.py | 29 ++++++-------- kdb-bot/src/modules/level/default-level.json | 2 +- kdb-bot/src/modules/level/level_seeder.py | 4 +- .../modules/level/service/level_service.py | 25 ++++++++++-- 9 files changed, 119 insertions(+), 27 deletions(-) create mode 100644 kdb-bot/src/modules/level/configuration/default_level_settings.py create mode 100644 kdb-bot/src/modules/level/configuration/level_server_settings.py diff --git a/kdb-bot/src/bot/config/appsettings.edrafts-pc.json b/kdb-bot/src/bot/config/appsettings.edrafts-pc.json index 9deca01737..eca8346df9 100644 --- a/kdb-bot/src/bot/config/appsettings.edrafts-pc.json +++ b/kdb-bot/src/bot/config/appsettings.edrafts-pc.json @@ -76,7 +76,12 @@ }, "BootLog": { "910199451145076828": { - "LoginMessageChannelId": "910199452915093588" + "LoginMessageChannelId": 910199452667637892 + } + }, + "Level": { + "910199451145076828": { + "ChangedLevelNotificationChannelId": 910199452915093588 } }, "Permission": { diff --git a/kdb-bot/src/bot/startup_settings_extension.py b/kdb-bot/src/bot/startup_settings_extension.py index 4dcee8bf4d..655ccd7b6c 100644 --- a/kdb-bot/src/bot/startup_settings_extension.py +++ b/kdb-bot/src/bot/startup_settings_extension.py @@ -11,6 +11,7 @@ from bot_core.configuration.bot_logging_settings import BotLoggingSettings from bot_core.configuration.bot_settings import BotSettings from modules.base.configuration.base_settings import BaseSettings from modules.boot_log.configuration.boot_log_settings import BootLogSettings +from modules.level.configuration.level_settings import LevelSettings from modules.permission.configuration.permission_settings import PermissionSettings @@ -35,6 +36,7 @@ class StartupSettingsExtension(StartupExtensionABC): self._configure_settings_with_sub_settings(configuration, BotSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, BaseSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, BootLogSettings, lambda x: x.servers, lambda x: x.id) + self._configure_settings_with_sub_settings(configuration, LevelSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, PermissionSettings, lambda x: x.servers, lambda x: x.id) self._configure_settings_with_sub_settings(configuration, BotLoggingSettings, lambda x: x.files, lambda x: x.key) diff --git a/kdb-bot/src/bot_core/service/message_service.py b/kdb-bot/src/bot_core/service/message_service.py index 7094236d8b..6a43f32cc6 100644 --- a/kdb-bot/src/bot_core/service/message_service.py +++ b/kdb-bot/src/bot_core/service/message_service.py @@ -49,7 +49,7 @@ class MessageService(MessageServiceABC): self._db.save_changes() self._logger.info(__name__, f'Deleted message {message}') - async def send_channel_message(self, channel: discord.TextChannel, message: Union[str, discord.Embed], without_tracking=False): + async def send_channel_message(self, channel: discord.TextChannel, message: Union[str, discord.Embed], is_persistent: bool = False, wait_before_delete: int = None, without_tracking=False): self._logger.debug(__name__, f'Try to send message\n\t{message}\n\tto: {channel}') msg = None try: @@ -64,6 +64,13 @@ class MessageService(MessageServiceABC): if not without_tracking: self._clients.append_sent_message_count(self._bot.user.id, channel.guild.id, 1) self._db.save_changes() + + if wait_before_delete is not None: + await asyncio.sleep(wait_before_delete) + + if is_persistent: + return + await self.delete_message(msg, without_tracking) async def send_dm_message(self, message: Union[str, discord.Embed], receiver: Union[discord.User, discord.Member], without_tracking=False): diff --git a/kdb-bot/src/modules/level/configuration/default_level_settings.py b/kdb-bot/src/modules/level/configuration/default_level_settings.py new file mode 100644 index 0000000000..3687ab83a9 --- /dev/null +++ b/kdb-bot/src/modules/level/configuration/default_level_settings.py @@ -0,0 +1,39 @@ +import traceback + +from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC +from cpl_core.console import Console +from cpl_query.extension import List + +from bot_data.model.level import Level + + +class DefaultLevelSettings(ConfigurationModelABC): + + def __init__(self): + ConfigurationModelABC.__init__(self) + + self._levels = List(Level) + self._level_header = '' + + @property + def levels(self) -> List[Level]: + return self._levels + + @property + def level_header(self) -> str: + return self._level_header + + def from_dict(self, settings: dict): + try: + self._level_header = settings['LevelHeader'] + for level in settings['Levels']: + self._levels.append(Level( + level['Name'], + level['Color'], + int(level['MinXp']), + int(level['Permissions']), + None + )) + except Exception as e: + Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') + Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') diff --git a/kdb-bot/src/modules/level/configuration/level_server_settings.py b/kdb-bot/src/modules/level/configuration/level_server_settings.py new file mode 100644 index 0000000000..85985cffc3 --- /dev/null +++ b/kdb-bot/src/modules/level/configuration/level_server_settings.py @@ -0,0 +1,29 @@ +import traceback + +from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC +from cpl_core.console import Console + + +class LevelServerSettings(ConfigurationModelABC): + + def __init__(self): + ConfigurationModelABC.__init__(self) + + self._id: int = 0 + self._changed_level_notification_channel = 0 + + @property + def id(self) -> int: + return self._id + + @property + def changed_level_notification_channel(self) -> int: + return self._changed_level_notification_channel + + def from_dict(self, settings: dict): + try: + self._id = int(settings['Id']) + self._changed_level_notification_channel = int(settings['ChangedLevelNotificationChannelId']) + except Exception as e: + Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') + Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') diff --git a/kdb-bot/src/modules/level/configuration/level_settings.py b/kdb-bot/src/modules/level/configuration/level_settings.py index 6f38e31b1a..7962941ca0 100644 --- a/kdb-bot/src/modules/level/configuration/level_settings.py +++ b/kdb-bot/src/modules/level/configuration/level_settings.py @@ -4,7 +4,7 @@ from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC from cpl_core.console import Console from cpl_query.extension import List -from bot_data.model.level import Level +from modules.level.configuration.level_server_settings import LevelServerSettings class LevelSettings(ConfigurationModelABC): @@ -12,28 +12,21 @@ class LevelSettings(ConfigurationModelABC): def __init__(self): ConfigurationModelABC.__init__(self) - self._levels = List(Level) - self._level_header = '' + self._servers: List[LevelServerSettings] = List() @property - def levels(self) -> List[Level]: - return self._levels - - @property - def level_header(self) -> str: - return self._level_header + def servers(self) -> List[LevelServerSettings]: + return self._servers def from_dict(self, settings: dict): try: - self._level_header = settings['LevelHeader'] - for level in settings['Levels']: - self._levels.append(Level( - level['Name'], - level['Color'], - int(level['MinXp']), - int(level['Permissions']), - None - )) + servers = List(LevelServerSettings) + for s in settings: + st = LevelServerSettings() + settings[s]['Id'] = s + st.from_dict(settings[s]) + servers.append(st) + self._servers = servers except Exception as e: Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {type(self).__name__} settings') Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') diff --git a/kdb-bot/src/modules/level/default-level.json b/kdb-bot/src/modules/level/default-level.json index 451e7544cd..047b811a28 100644 --- a/kdb-bot/src/modules/level/default-level.json +++ b/kdb-bot/src/modules/level/default-level.json @@ -1,5 +1,5 @@ { - "Level": { + "DefaultLevel": { "LevelHeader": "~~~ Level ~~~", "Levels": [ { diff --git a/kdb-bot/src/modules/level/level_seeder.py b/kdb-bot/src/modules/level/level_seeder.py index 377bfd2a6d..9a1148bb49 100644 --- a/kdb-bot/src/modules/level/level_seeder.py +++ b/kdb-bot/src/modules/level/level_seeder.py @@ -9,12 +9,12 @@ from bot_data.abc.server_repository_abc import ServerRepositoryABC from bot_data.model.level import Level from bot_data.model.server import Server from bot_data.service.level_repository_service import LevelRepositoryService -from modules.level.configuration.level_settings import LevelSettings +from modules.level.configuration.default_level_settings import DefaultLevelSettings class LevelSeeder(DataSeederABC): - def __init__(self, logger: DatabaseLogger, levels: LevelSettings, level_repo: LevelRepositoryService, servers: ServerRepositoryABC, bot: DiscordBotServiceABC): + def __init__(self, logger: DatabaseLogger, levels: DefaultLevelSettings, level_repo: LevelRepositoryService, servers: ServerRepositoryABC, bot: DiscordBotServiceABC): DataSeederABC.__init__(self) self._logger = logger diff --git a/kdb-bot/src/modules/level/service/level_service.py b/kdb-bot/src/modules/level/service/level_service.py index 292d548aad..6385b9ae67 100644 --- a/kdb-bot/src/modules/level/service/level_service.py +++ b/kdb-bot/src/modules/level/service/level_service.py @@ -1,35 +1,42 @@ import asyncio import discord +from cpl_core.configuration import ConfigurationABC from cpl_core.database.context import DatabaseContextABC from cpl_core.logging import LoggerABC from cpl_discord.container import Guild, Role, Member from cpl_discord.service import DiscordBotServiceABC +from bot_core.service.message_service import MessageService from bot_data.model.level import Level from bot_data.model.user import User from bot_data.service.level_repository_service import LevelRepositoryService from bot_data.service.server_repository_service import ServerRepositoryService from bot_data.service.user_repository_service import UserRepositoryService +from modules.level.configuration.level_server_settings import LevelServerSettings class LevelService: def __init__( self, + config: ConfigurationABC, logger: LoggerABC, db: DatabaseContextABC, levels: LevelRepositoryService, users: UserRepositoryService, servers: ServerRepositoryService, - bot: DiscordBotServiceABC + bot: DiscordBotServiceABC, + message_service: MessageService ): + self._config = config self._logger = logger self._db = db self._levels = levels self._users = users self._servers = servers self._bot = bot + self._message_service = message_service def get_level(self, user: User) -> Level: levels = self._levels.get_levels_by_server_id(user.server.server_id).order_by(lambda l: l.min_xp) @@ -39,6 +46,12 @@ class LevelService: level_names = self._levels.get_levels_by_server_id(user.server.server_id).select(lambda l: l.name) guild: Guild = self._bot.guilds.where(lambda g: g.id == user.server.discord_server_id).single() member: Member = guild.members.where(lambda m: m.id == user.discord_id).single() + + level = self.get_level(user) + level_role: Role = guild.roles.where(lambda r: r.name == level.name).single() + if level_role in member.roles: + return + for role in member.roles: if role.name not in level_names.to_list(): continue @@ -50,9 +63,6 @@ class LevelService: except Exception as e: self._logger.error(__name__, f'Removing role {role.name} from {member.name} failed!', e) - level_role: Role = guild.roles.where(lambda r: r.name == self.get_level(user).name).single() - if level_role in member.roles: - return try: self._logger.debug(__name__, f'Try to add role {level_role.name} to {member.name}') await member.add_roles(level_role) @@ -60,6 +70,13 @@ class LevelService: except Exception as e: self._logger.error(__name__, f'Adding role {level_role.name} to {member.name} failed!', e) + level_settings: LevelServerSettings = self._config.get_configuration(f'LevelServerSettings_{guild.id}') + await self._message_service.send_channel_message( + self._bot.get_channel(level_settings.changed_level_notification_channel), + f'<@{member.id}> ist nun Level {level.name}', + is_persistent=True + ) + async def check_level(self, member: discord.Member): if member.bot: return