forked from sh-edraft.de/sh_discord_bot
		
	Added logic to handle level by xp #25
This commit is contained in:
		| @@ -63,7 +63,7 @@ class LevelRepositoryService(LevelRepositoryABC): | ||||
|     def get_levels_by_server_id(self, server_id: int) -> List[Level]: | ||||
|         levels = List(Level) | ||||
|         self._logger.trace(__name__, f'Send SQL command: {Level.get_select_by_server_id_string(server_id)}') | ||||
|         results = self._context.select(Level.get_select_by_server_id_string(server_id))[0] | ||||
|         results = self._context.select(Level.get_select_by_server_id_string(server_id)) | ||||
|  | ||||
|         for result in results: | ||||
|             self._logger.trace(__name__, f'Get level with id {result[0]}') | ||||
|   | ||||
| @@ -13,14 +13,20 @@ class LevelSettings(ConfigurationModelABC): | ||||
|         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: | ||||
|             for level in settings: | ||||
|             self._level_header = settings['LevelHeader'] | ||||
|             for level in settings['Levels']: | ||||
|                 self._levels.append(Level( | ||||
|                     level['Name'], | ||||
|                     level['Color'], | ||||
|   | ||||
| @@ -1,28 +1,31 @@ | ||||
| { | ||||
|   "Level": [ | ||||
|     { | ||||
|       "Name": "Newbie", | ||||
|       "Color": "0x1abc9c", | ||||
|       "MinXp": 0, | ||||
|       "Permissions": 968552209984 | ||||
|     }, | ||||
|     { | ||||
|       "Name": "Keks", | ||||
|       "Color": "0x2ecc71", | ||||
|       "MinXp": 100, | ||||
|       "Permissions": 1002928856640 | ||||
|     }, | ||||
|     { | ||||
|       "Name": "Doppelkeks", | ||||
|       "Color": "0x3498db", | ||||
|       "MinXp": 200, | ||||
|       "Permissions": 1071849660224 | ||||
|     }, | ||||
|     { | ||||
|       "Name": "Auror", | ||||
|       "Color": "0xf1c40f", | ||||
|       "MinXp": 300, | ||||
|       "Permissions": 1089042120513 | ||||
|     } | ||||
|   ] | ||||
|   "Level": { | ||||
|     "LevelHeader": "~~~ Level ~~~", | ||||
|     "Levels": [ | ||||
|       { | ||||
|         "Name": "Newbie", | ||||
|         "Color": "0x1abc9c", | ||||
|         "MinXp": 0, | ||||
|         "Permissions": 968552209984 | ||||
|       }, | ||||
|       { | ||||
|         "Name": "Keks", | ||||
|         "Color": "0x2ecc71", | ||||
|         "MinXp": 100, | ||||
|         "Permissions": 1002928856640 | ||||
|       }, | ||||
|       { | ||||
|         "Name": "Doppelkeks", | ||||
|         "Color": "0x3498db", | ||||
|         "MinXp": 200, | ||||
|         "Permissions": 1071849660224 | ||||
|       }, | ||||
|       { | ||||
|         "Name": "Auror", | ||||
|         "Color": "0xf1c40f", | ||||
|         "MinXp": 300, | ||||
|         "Permissions": 1089042120513 | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
| } | ||||
							
								
								
									
										26
									
								
								kdb-bot/src/modules/level/events/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								kdb-bot/src/modules/level/events/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| # -*- coding: utf-8 -*- | ||||
|  | ||||
| """ | ||||
| bot Keksdose bot | ||||
| ~~~~~~~~~~~~~~~~~~~ | ||||
|  | ||||
| Discord bot  for the Keksdose discord Server | ||||
|  | ||||
| :copyright: (c) 2022 sh-edraft.de | ||||
| :license: MIT, see LICENSE for more details. | ||||
|  | ||||
| """ | ||||
|  | ||||
| __title__ = 'modules.base.events' | ||||
| __author__ = 'Sven Heidemann' | ||||
| __license__ = 'MIT' | ||||
| __copyright__ = 'Copyright (c) 2022 sh-edraft.de' | ||||
| __version__ = '0.3.dev70' | ||||
|  | ||||
| from collections import namedtuple | ||||
|  | ||||
|  | ||||
| # imports: | ||||
|  | ||||
| VersionInfo = namedtuple('VersionInfo', 'major minor micro') | ||||
| version_info = VersionInfo(major='0', minor='3', micro='dev70') | ||||
							
								
								
									
										21
									
								
								kdb-bot/src/modules/level/events/level_on_message_event.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								kdb-bot/src/modules/level/events/level_on_message_event.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| import discord | ||||
| from cpl_discord.events import OnMessageABC | ||||
|  | ||||
| from bot_core.logging.message_logger import MessageLogger | ||||
| from modules.level.service.level_service import LevelService | ||||
|  | ||||
|  | ||||
| class LevelOnMessageEvent(OnMessageABC): | ||||
|  | ||||
|     def __init__( | ||||
|             self, | ||||
|             logger: MessageLogger, | ||||
|             level: LevelService | ||||
|     ): | ||||
|         OnMessageABC.__init__(self) | ||||
|         self._logger = logger | ||||
|         self._level = level | ||||
|  | ||||
|     async def on_message(self, message: discord.Message): | ||||
|         self._logger.debug(__name__, f'Module {type(self)} started') | ||||
|         await self._level.check_level(message.author) | ||||
| @@ -0,0 +1,23 @@ | ||||
| import discord | ||||
| from cpl_core.logging import LoggerABC | ||||
| from cpl_discord.events import OnVoiceStateUpdateABC | ||||
|  | ||||
| from modules.level.service.level_service import LevelService | ||||
|  | ||||
|  | ||||
| class LevelOnVoiceStateUpdateEvent(OnVoiceStateUpdateABC): | ||||
|  | ||||
|     def __init__( | ||||
|             self, | ||||
|             logger: LoggerABC, | ||||
|             level: LevelService | ||||
|     ): | ||||
|         OnVoiceStateUpdateABC.__init__(self) | ||||
|         self._logger = logger | ||||
|         self._level = level | ||||
|  | ||||
|         self._logger.info(__name__, f'Module {type(self)} loaded') | ||||
|  | ||||
|     async def on_voice_state_update(self, member: discord.Member, before: discord.VoiceState, after: discord.VoiceState): | ||||
|         self._logger.debug(__name__, f'Module {type(self)} started') | ||||
|         await self._level.check_level(member) | ||||
| @@ -3,10 +3,13 @@ import os | ||||
| from cpl_core.configuration import ConfigurationABC | ||||
| from cpl_core.dependency_injection import ServiceCollectionABC | ||||
| from cpl_core.environment import ApplicationEnvironmentABC | ||||
| from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum | ||||
| from cpl_discord.service.discord_collection_abc import DiscordCollectionABC | ||||
|  | ||||
| from bot_core.abc.module_abc import ModuleABC | ||||
| from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum | ||||
| from modules.level.events.level_on_message_event import LevelOnMessageEvent | ||||
| from modules.level.events.level_on_voice_state_update_event import LevelOnVoiceStateUpdateEvent | ||||
| from modules.level.level_seeder import LevelSeeder | ||||
| from modules.level.service.level_service import LevelService | ||||
|  | ||||
| @@ -25,3 +28,6 @@ class LevelModule(ModuleABC): | ||||
|     def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC): | ||||
|         services.add_transient(LevelSeeder) | ||||
|         services.add_transient(LevelService) | ||||
|  | ||||
|         self._dc.add_event(DiscordEventTypesEnum.on_message.value, LevelOnMessageEvent) | ||||
|         self._dc.add_event(DiscordEventTypesEnum.on_voice_state_update.value, LevelOnVoiceStateUpdateEvent) | ||||
|   | ||||
| @@ -18,14 +18,16 @@ class LevelSeeder(DataSeederABC): | ||||
|         DataSeederABC.__init__(self) | ||||
|  | ||||
|         self._logger = logger | ||||
|         self._default_levels = levels.levels.order_by_descending(lambda l: l.min_xp) | ||||
|         self._levels = level_repo | ||||
|         self._servers = servers | ||||
|         self._bot = bot | ||||
|  | ||||
|         self._level_header = levels.level_header | ||||
|         self._default_levels = levels.levels.order_by_descending(lambda l: l.min_xp) | ||||
|  | ||||
|     async def _create_level(self, level: Level, guild: Guild, server: Server): | ||||
|         try: | ||||
|             if guild.roles.where(lambda r: r.name == level.name).count() > 0: | ||||
|             if guild.roles.where(lambda r: r.name == level.name).first_or_default() is not None: | ||||
|                 return | ||||
|  | ||||
|             await guild.create_role(name=level.name, colour=Colour(int(level.color, 16)), hoist=False, mentionable=True, permissions=Permissions(level.permissions)) | ||||
| @@ -39,8 +41,8 @@ class LevelSeeder(DataSeederABC): | ||||
|         # create levels | ||||
|         for guild in self._bot.guilds: | ||||
|             created_default = False | ||||
|             if guild.roles.where(lambda r: r.name == '___ Level ___').count() == 0: | ||||
|                 await guild.create_role(name='___ Level ___') | ||||
|             if guild.roles.where(lambda r: r.name == self._level_header).first_or_default() is None: | ||||
|                 await guild.create_role(name=self._level_header) | ||||
|  | ||||
|             server = self._servers.find_server_by_discord_id(guild.id) | ||||
|             if server is None: | ||||
| @@ -64,7 +66,7 @@ class LevelSeeder(DataSeederABC): | ||||
|             if created_default: | ||||
|                 continue | ||||
|  | ||||
|             position_above_levels = guild.roles.where(lambda r: r.name == '~~~ Level ~~~').single().position | ||||
|             position_above_levels = guild.roles.where(lambda r: r.name == self._level_header).single().position | ||||
|             for role in guild.roles.order_by_descending(lambda r: r.position): | ||||
|                 if levels.where(lambda l: l.name == role.name).count() == 0: | ||||
|                     continue | ||||
|   | ||||
| @@ -1,3 +1,4 @@ | ||||
| import discord | ||||
| from cpl_core.database.context import DatabaseContextABC | ||||
| from cpl_core.logging import LoggerABC | ||||
| from cpl_discord.container import Guild, Role, Member | ||||
| @@ -6,6 +7,7 @@ from cpl_discord.service import DiscordBotServiceABC | ||||
| 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 | ||||
|  | ||||
|  | ||||
| @@ -17,17 +19,19 @@ class LevelService: | ||||
|             db: DatabaseContextABC, | ||||
|             levels: LevelRepositoryService, | ||||
|             users: UserRepositoryService, | ||||
|             servers: ServerRepositoryService, | ||||
|             bot: DiscordBotServiceABC | ||||
|     ): | ||||
|         self._logger = logger | ||||
|         self._db = db | ||||
|         self._levels = levels | ||||
|         self._users = users | ||||
|         self._servers = servers | ||||
|         self._bot = bot | ||||
|  | ||||
|     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) | ||||
|         return levels.where(lambda l: l.min_xp > user.xp).first() | ||||
|         return levels.where(lambda l: user.xp >= l.min_xp).first() | ||||
|  | ||||
|     async def set_level(self, user: User): | ||||
|         level_names = self._levels.get_levels_by_server_id(user.server.server_id).select(lambda l: l.name) | ||||
| @@ -45,9 +49,22 @@ class LevelService: | ||||
|             except Exception as e: | ||||
|                 self._logger.error(__name__, f'Removing role {role.name} from {member.name} failed!', e) | ||||
|  | ||||
|         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) | ||||
|             self._logger.info(__name__, f'Add role {level_role.name} to {member.name}') | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f'Adding role {level_role.name} to {member.name} failed!', e) | ||||
|  | ||||
|     async def check_level(self, member: discord.Member): | ||||
|         if member.bot: | ||||
|             return | ||||
|  | ||||
|         server = self._servers.get_server_by_discord_id(member.guild.id) | ||||
|         user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id) | ||||
|         if user is None: | ||||
|             self._logger.warn(__name__, f'User not found {member.guild.name}@{member.name}') | ||||
|  | ||||
|         await self.set_level(user) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user