diff --git a/kdb-bot/src/bot/config b/kdb-bot/src/bot/config index fcee4292..ac704682 160000 --- a/kdb-bot/src/bot/config +++ b/kdb-bot/src/bot/config @@ -1 +1 @@ -Subproject commit fcee42921a6cbb20f4e022e12d9a610864f053f1 +Subproject commit ac7046820f3410f55e779797126d9410c6bcdc9f diff --git a/kdb-bot/src/bot_api/config b/kdb-bot/src/bot_api/config index 27289afd..3c2a8630 160000 --- a/kdb-bot/src/bot_api/config +++ b/kdb-bot/src/bot_api/config @@ -1 +1 @@ -Subproject commit 27289afd5e2d020cd9fcec62a682204a93688f25 +Subproject commit 3c2a863022e6656927b9360875695a6bcdc70ac9 diff --git a/kdb-bot/src/modules/base/base_module.py b/kdb-bot/src/modules/base/base_module.py index cfc4475c..492a5ee4 100644 --- a/kdb-bot/src/modules/base/base_module.py +++ b/kdb-bot/src/modules/base/base_module.py @@ -32,6 +32,9 @@ from modules.base.events.base_on_voice_state_update_event import ( from modules.base.events.base_on_voice_state_update_event_help_channel import ( BaseOnVoiceStateUpdateEventHelpChannel, ) +from modules.base.events.base_on_voice_state_update_event_scheduled_event_bonus import ( + BaseOnVoiceStateUpdateEventScheduledEventBonus, +) from modules.base.helper.base_reaction_handler import BaseReactionHandler from modules.base.service.base_helper_service import BaseHelperService from modules.base.service.event_service import EventService @@ -81,6 +84,10 @@ class BaseModule(ModuleABC): DiscordEventTypesEnum.on_voice_state_update.value, BaseOnVoiceStateUpdateEventHelpChannel, ) + self._dc.add_event( + DiscordEventTypesEnum.on_voice_state_update.value, + BaseOnVoiceStateUpdateEventScheduledEventBonus, + ) self._dc.add_event( DiscordEventTypesEnum.on_scheduled_event_update.value, BaseOnScheduledEventUpdateEvent, diff --git a/kdb-bot/src/modules/base/configuration/base_server_settings.py b/kdb-bot/src/modules/base/configuration/base_server_settings.py index f9555890..c6a7e9c4 100644 --- a/kdb-bot/src/modules/base/configuration/base_server_settings.py +++ b/kdb-bot/src/modules/base/configuration/base_server_settings.py @@ -79,7 +79,7 @@ class BaseServerSettings(ConfigurationModelABC): self._max_message_xp_per_hour = int(settings["MaxMessageXpPerHour"]) self._xp_per_ontime_hour = int(settings["XpPerOntimeHour"]) self._xp_per_event_participation = ( - 0 if "XpPerEventParticipation" in settings else settings["XpPerEventParticipation"] + 0 if "XpPerEventParticipation" not in settings else settings["XpPerEventParticipation"] ) for index in settings["AFKChannelIds"]: self._afk_channel_ids.append(int(index)) diff --git a/kdb-bot/src/modules/base/events/base_on_scheduled_event_update_event.py b/kdb-bot/src/modules/base/events/base_on_scheduled_event_update_event.py index 456599ee..5b9cf901 100644 --- a/kdb-bot/src/modules/base/events/base_on_scheduled_event_update_event.py +++ b/kdb-bot/src/modules/base/events/base_on_scheduled_event_update_event.py @@ -4,6 +4,7 @@ from cpl_discord.events.on_scheduled_event_update_abc import OnScheduledEventUpd from cpl_discord.service import DiscordBotServiceABC from discord import EventStatus +from modules.base.model.active_event import ActiveEvent from modules.base.service.event_service import EventService @@ -25,11 +26,14 @@ class BaseOnScheduledEventUpdateEvent(OnScheduledEventUpdateABC): # save started event if before.status != after.status and after.status == EventStatus.active: - self._events.add_event(after) + self._events.add_event(ActiveEvent(after)) # delete stopped event if before.status != after.status and ( after.status.value == EventStatus.cancelled.value or after.status.value == EventStatus.completed.value ): - self._events.remove_event(after) + event = self._events.get_active_event(after) + if event is None: + return + self._events.remove_event(event) self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_scheduled_event_bonus.py b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_scheduled_event_bonus.py new file mode 100644 index 00000000..54050851 --- /dev/null +++ b/kdb-bot/src/modules/base/events/base_on_voice_state_update_event_scheduled_event_bonus.py @@ -0,0 +1,66 @@ +import discord +from cpl_core.configuration import ConfigurationABC +from cpl_core.database.context import DatabaseContextABC +from cpl_core.logging import LoggerABC +from cpl_discord.events import OnVoiceStateUpdateABC + +from bot_core.helper.event_checks import EventChecks +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from modules.base.abc.base_helper_abc import BaseHelperABC +from modules.base.configuration.base_server_settings import BaseServerSettings +from modules.base.service.event_service import EventService + + +class BaseOnVoiceStateUpdateEventScheduledEventBonus(OnVoiceStateUpdateABC): + def __init__( + self, + config: ConfigurationABC, + logger: LoggerABC, + base_helper: BaseHelperABC, + servers: ServerRepositoryABC, + users: UserRepositoryABC, + events: EventService, + db: DatabaseContextABC, + ): + OnVoiceStateUpdateABC.__init__(self) + self._config = config + self._logger = logger + self._base_helper = base_helper + self._servers = servers + self._users = users + self._events = events + self._db = db + + self._logger.info(__name__, f"Module {type(self)} loaded") + + @EventChecks.check_is_ready() + 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") + if member.bot or after.channel is None: + self._logger.debug(__name__, f"Module {type(self)} stopped") + return + + active_event = self._events.get_active_event_by_channel_id(after.channel.id) + if active_event is None: + self._logger.debug(__name__, f"Module {type(self)} stopped") + return + + server = self._servers.get_server_by_discord_id(member.guild.id) + user = self._users.get_user_by_discord_id_and_server_id(member.id, server.server_id) + if active_event.participants.any(lambda x: x.user_id == user.user_id): + self._logger.debug(__name__, f"Module {type(self)} stopped") + return + + settings: BaseServerSettings = self._base_helper.get_config(server.discord_server_id) + user.xp += settings.xp_per_event_participation + self._users.update_user(user) + self._db.save_changes() + active_event.participants.append(user) + + self._logger.debug(__name__, f"Module {type(self)} stopped") diff --git a/kdb-bot/src/modules/base/model/__init__.py b/kdb-bot/src/modules/base/model/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/kdb-bot/src/modules/base/model/active_event.py b/kdb-bot/src/modules/base/model/active_event.py new file mode 100644 index 00000000..63861e0c --- /dev/null +++ b/kdb-bot/src/modules/base/model/active_event.py @@ -0,0 +1,18 @@ +import discord +from cpl_query.extension import List + +from bot_data.model.user import User + + +class ActiveEvent: + def __init__(self, event: discord.ScheduledEvent): + self._event = event + self._participants = List(User) + + @property + def event(self) -> discord.ScheduledEvent: + return self._event + + @property + def participants(self) -> List[User]: + return self._participants diff --git a/kdb-bot/src/modules/base/service/event_service.py b/kdb-bot/src/modules/base/service/event_service.py index 03cb0b02..8073b3d3 100644 --- a/kdb-bot/src/modules/base/service/event_service.py +++ b/kdb-bot/src/modules/base/service/event_service.py @@ -1,18 +1,30 @@ +from typing import Optional + +import discord from cpl_query.extension import List -from discord import ScheduledEvent + +from modules.base.model.active_event import ActiveEvent class EventService: def __init__(self): - self._active_events = List(ScheduledEvent) + self._active_events = List(ActiveEvent) - def add_event(self, event: ScheduledEvent): + def add_event(self, event: ActiveEvent): if self._active_events.contains(event): return self._active_events.add(event) - def remove_event(self, event: ScheduledEvent): + def get_active_event(self, event: discord.ScheduledEvent) -> Optional[ActiveEvent]: + return self._active_events.where(lambda x: x.event.id == event.id).single_or_default() + + def get_active_event_by_channel_id(self, channel_id: int) -> Optional[ActiveEvent]: + return self._active_events.where( + lambda x: x.event.channel is not None and x.event.channel.id == channel_id + ).single_or_default() + + def remove_event(self, event: ActiveEvent): if not self._active_events.contains(event): return