diff --git a/kdb-bot/src/modules/achievements/achievement_attribute_resolver.py b/kdb-bot/src/modules/achievements/achievement_attribute_resolver.py new file mode 100644 index 00000000..9006da17 --- /dev/null +++ b/kdb-bot/src/modules/achievements/achievement_attribute_resolver.py @@ -0,0 +1,43 @@ +from typing import List + +from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC +from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC +from bot_data.abc.client_repository_abc import ClientRepositoryABC +from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC +from bot_data.abc.level_repository_abc import LevelRepositoryABC +from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC +from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC +from bot_data.abc.user_joined_voice_channel_repository_abc import UserJoinedVoiceChannelRepositoryABC +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.user import User + + +class AchievementAttributeResolver: + def __init__( + self, + auto_roles: AutoRoleRepositoryABC, + clients: ClientRepositoryABC, + known_users: KnownUserRepositoryABC, + levels: LevelRepositoryABC, + servers: ServerRepositoryABC, + user_joined_servers: UserJoinedServerRepositoryABC, + user_joined_voice_channels: UserJoinedVoiceChannelRepositoryABC, + user_joined_game_server: UserJoinedGameServerRepositoryABC, + users: UserRepositoryABC, + achievements: AchievementRepositoryABC, + ): + self._auto_roles = auto_roles + self._clients = clients + self._known_users = known_users + self._levels = levels + self._servers = servers + self._user_joined_servers = user_joined_servers + self._user_joined_voice_channels = user_joined_voice_channels + self._user_joined_game_server = user_joined_game_server + self._users = users + self._achievements = achievements + + def get_played_on_game_server(self, user: User) -> List[str]: + joins = self._user_joined_game_server.get_user_joined_game_servers_by_user_id(user.id) + return joins.select(lambda x: x.name) diff --git a/kdb-bot/src/modules/achievements/achievement_service.py b/kdb-bot/src/modules/achievements/achievement_service.py index 23fb3754..f6bf30ad 100644 --- a/kdb-bot/src/modules/achievements/achievement_service.py +++ b/kdb-bot/src/modules/achievements/achievement_service.py @@ -11,6 +11,7 @@ from bot_data.abc.achievement_repository_abc import AchievementRepositoryABC from bot_data.model.achievement import Achievement from bot_data.model.user import User from bot_data.model.user_got_achievement import UserGotAchievement +from modules.achievements.achievement_attribute_resolver import AchievementAttributeResolver from modules.achievements.model.achievement_attribute import AchievementAttribute @@ -23,6 +24,7 @@ class AchievementService: achievements: AchievementRepositoryABC, db: DatabaseContextABC, message_service: MessageService, + resolver: AchievementAttributeResolver, t: TranslatePipe, ): self._config = config @@ -42,28 +44,32 @@ class AchievementService: AchievementAttribute("reaction_count", lambda user: user.reaction_count, "number"), AchievementAttribute("ontime", lambda user: user.ontime, "number"), AchievementAttribute("level", lambda user: user.level, "Level"), + # special cases + AchievementAttribute( + "played_on_game_server", lambda user: resolver.get_played_on_game_server(user), "GameServer" + ), + AchievementAttribute("last_single_ontime_hours", lambda user: user.level, "GameServer"), ] ) + self._operators = { + "==": lambda value, expected_value: value == expected_value, + "!=": lambda value, expected_value: value != expected_value, + "<=": lambda value, expected_value: value <= expected_value, + ">=": lambda value, expected_value: value >= expected_value, + "<": lambda value, expected_value: value < expected_value, + ">": lambda value, expected_value: value > expected_value, + "contains": lambda value, expected_value: expected_value in value, + } + + def get_operators(self) -> list[str]: + return [x for x in self._operators.keys()] + def get_attributes(self) -> List[AchievementAttribute]: return self._attributes def _match(self, value: str, operator: str, expected_value: str) -> bool: - match operator: - case "==": - return value == expected_value - case "!=": - return value != expected_value - case "<=": - return value <= expected_value - case ">=": - return value >= expected_value - case "<": - return value < expected_value - case ">": - return value > expected_value - case _: - raise ValueError(f"Invalid operator: ${operator}") + return self._operators[operator](value, expected_value) def has_user_achievement_already(self, user: User, achievement: Achievement) -> bool: user_achievements = self._achievements.get_achievements_by_user_id(user.id)