From 4c6ed51bd1f1fd3db69e83fe9d4222ff532cd9c0 Mon Sep 17 00:00:00 2001 From: Sven Heidemann Date: Sun, 5 Mar 2023 13:47:30 +0100 Subject: [PATCH] Improved game server handling for ontime #238 --- .../abc/user_game_ident_repository_abc.py | 47 +++++++ .../user_joined_game_server_repository_abc.py | 4 - kdb-bot/src/bot_data/data_module.py | 3 + .../user_joined_game_server_migration.py | 20 +++ kdb-bot/src/bot_data/model/user.py | 12 ++ kdb-bot/src/bot_data/model/user_game_ident.py | 131 ++++++++++++++++++ .../user_game_ident_repository_service.py | 111 +++++++++++++++ ...r_joined_game_server_repository_service.py | 49 +------ kdb-bot/src/bot_graphql/model/user.gql | 2 - .../model/userJoinedGameServer.gql | 4 +- .../user_joined_game_server_mutation.py | 30 +++- kdb-bot/src/bot_graphql/queries/user_query.py | 5 - .../modules/base/command/register_group.py | 30 +++- .../modules/base/command/unregister_group.py | 40 ++++-- 14 files changed, 412 insertions(+), 76 deletions(-) create mode 100644 kdb-bot/src/bot_data/abc/user_game_ident_repository_abc.py create mode 100644 kdb-bot/src/bot_data/model/user_game_ident.py create mode 100644 kdb-bot/src/bot_data/service/user_game_ident_repository_service.py diff --git a/kdb-bot/src/bot_data/abc/user_game_ident_repository_abc.py b/kdb-bot/src/bot_data/abc/user_game_ident_repository_abc.py new file mode 100644 index 00000000..fbaa0831 --- /dev/null +++ b/kdb-bot/src/bot_data/abc/user_game_ident_repository_abc.py @@ -0,0 +1,47 @@ +from abc import ABC, abstractmethod + +from cpl_query.extension import List + +from bot_data.model.user_game_ident import UserGameIdent + + +class UserGameIdentRepositoryABC(ABC): + @abstractmethod + def __init__(self): + pass + + @abstractmethod + def get_user_game_idents(self) -> List[UserGameIdent]: + pass + + @abstractmethod + def get_user_game_ident_by_id(self, id: int) -> UserGameIdent: + pass + + @abstractmethod + def get_user_game_ident_by_ident(self, ident: str) -> UserGameIdent: + pass + + @abstractmethod + def find_user_game_ident_by_ident(self, ident: str) -> UserGameIdent: + pass + + @abstractmethod + def get_user_game_idents_by_user_id(self, user_id: int) -> List[UserGameIdent]: + pass + + @abstractmethod + def add_user_game_ident(self, user_game_ident: UserGameIdent): + pass + + @abstractmethod + def update_user_game_ident(self, user_game_ident: UserGameIdent): + pass + + @abstractmethod + def delete_user_game_ident(self, user_game_ident: UserGameIdent): + pass + + @abstractmethod + def delete_user_game_ident_by_user_id(self, user_id: int): + pass diff --git a/kdb-bot/src/bot_data/abc/user_joined_game_server_repository_abc.py b/kdb-bot/src/bot_data/abc/user_joined_game_server_repository_abc.py index 266e90b5..97a0358b 100644 --- a/kdb-bot/src/bot_data/abc/user_joined_game_server_repository_abc.py +++ b/kdb-bot/src/bot_data/abc/user_joined_game_server_repository_abc.py @@ -11,10 +11,6 @@ class UserJoinedGameServerRepositoryABC(ABC): def __init__(self): pass - # @abstractmethod - # def get_game_server_by_api_key(self) -> List[UserJoinedGameServer]: - # pass - @abstractmethod def get_user_joined_game_servers(self) -> List[UserJoinedGameServer]: pass diff --git a/kdb-bot/src/bot_data/data_module.py b/kdb-bot/src/bot_data/data_module.py index d180e97e..fb37c20d 100644 --- a/kdb-bot/src/bot_data/data_module.py +++ b/kdb-bot/src/bot_data/data_module.py @@ -13,6 +13,7 @@ from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC 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_game_ident_repository_abc import UserGameIdentRepositoryABC 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 ( @@ -32,6 +33,7 @@ from bot_data.service.known_user_repository_service import KnownUserRepositorySe from bot_data.service.level_repository_service import LevelRepositoryService from bot_data.service.seeder_service import SeederService from bot_data.service.server_repository_service import ServerRepositoryService +from bot_data.service.user_game_ident_repository_service import UserGameIdentRepositoryService from bot_data.service.user_joined_game_server_repository_service import UserJoinedGameServerRepositoryService from bot_data.service.user_joined_server_repository_service import ( UserJoinedServerRepositoryService, @@ -71,5 +73,6 @@ class DataModule(ModuleABC): UserMessageCountPerHourRepositoryService, ) services.add_transient(GameServerRepositoryABC, GameServerRepositoryService) + services.add_transient(UserGameIdentRepositoryABC, UserGameIdentRepositoryService) services.add_transient(SeederService) diff --git a/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py b/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py index 6e1588b2..22302a9f 100644 --- a/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py +++ b/kdb-bot/src/bot_data/migration/user_joined_game_server_migration.py @@ -52,6 +52,26 @@ class UserJoinedGameServerMigration(MigrationABC): ) ) + self._cursor.execute( + str( + f""" + CREATE TABLE IF NOT EXISTS `UserGameIdents` ( + `Id` BIGINT NOT NULL AUTO_INCREMENT, + `UserId` BIGINT NOT NULL, + `GameServerId` BIGINT NOT NULL, + `Ident` VARCHAR(255) NOT NULL, + `CreatedAt` DATETIME(6), + `LastModifiedAt` DATETIME(6), + FOREIGN KEY (`UserId`) REFERENCES Users(`UserId`), + FOREIGN KEY (`GameServerId`) REFERENCES GameServers(`Id`), + CONSTRAINT UC_UserGameIdent UNIQUE (`GameServerId`,`Ident`), + PRIMARY KEY(`Id`) + ); + """ + ) + ) + def downgrade(self): self._cursor.execute("DROP TABLE `GameServers`;") self._cursor.execute("DROP TABLE `UserJoinedGameServer`;") + self._cursor.execute("DROP TABLE `UserGameIdents`;") diff --git a/kdb-bot/src/bot_data/model/user.py b/kdb-bot/src/bot_data/model/user.py index 2c4c7a3d..9f975550 100644 --- a/kdb-bot/src/bot_data/model/user.py +++ b/kdb-bot/src/bot_data/model/user.py @@ -4,6 +4,7 @@ from typing import Optional from cpl_core.database import TableABC from cpl_core.dependency_injection import ServiceProviderABC from cpl_discord.service import DiscordBotServiceABC +from cpl_query.extension import List from bot_data.model.level import Level from bot_data.model.server import Server @@ -90,6 +91,17 @@ class User(TableABC): ujs: UserJoinedServerRepositoryABC = services.get_service(UserJoinedServerRepositoryABC) return ujs.find_active_user_joined_server_by_user_id(self.id) is None + @property + @ServiceProviderABC.inject + def game_idents( + self, + services: ServiceProviderABC, + ) -> List["UserGameIdent"]: + from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC + + game_idents_repo: UserGameIdentRepositoryABC = services.get_service(UserGameIdentRepositoryABC) + return game_idents_repo.get_user_game_idents_by_user_id(self.id) + @staticmethod def get_select_all_string() -> str: return str( diff --git a/kdb-bot/src/bot_data/model/user_game_ident.py b/kdb-bot/src/bot_data/model/user_game_ident.py new file mode 100644 index 00000000..6d6bf781 --- /dev/null +++ b/kdb-bot/src/bot_data/model/user_game_ident.py @@ -0,0 +1,131 @@ +from datetime import datetime + +from cpl_core.database import TableABC + +from bot_data.model.game_server import GameServer +from bot_data.model.user import User + + +class UserGameIdent(TableABC): + def __init__( + self, + user: User, + game_server: GameServer, + ident: str, + created_at: datetime = None, + modified_at: datetime = None, + id=0, + ): + self._id = id + self._user = user + self._game_server = game_server + self._ident = ident + + TableABC.__init__(self) + self._created_at = created_at if created_at is not None else self._created_at + self._modified_at = modified_at if modified_at is not None else self._modified_at + + @property + def id(self) -> int: + return self._id + + @property + def user(self) -> User: + return self._user + + @property + def game_server(self) -> GameServer: + return self._game_server + + @property + def ident(self) -> str: + return self._ident + + @staticmethod + def get_select_all_string() -> str: + return str( + f""" + SELECT * FROM `UserGameIdents`; + """ + ) + + @staticmethod + def get_select_by_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserGameIdents` + WHERE `Id` = {id}; + """ + ) + + @staticmethod + def get_select_by_ident_string(ident: str) -> str: + return str( + f""" + SELECT * FROM `UserGameIdents` + WHERE `Ident` = '{ident}'; + """ + ) + + @staticmethod + def get_select_by_user_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserGameIdents` + WHERE `UserId` = {id}; + """ + ) + + @staticmethod + def get_select_active_by_user_id_string(id: int) -> str: + return str( + f""" + SELECT * FROM `UserGameIdents` + WHERE `UserId` = {id} + AND `LeavedOn` IS NULL; + """ + ) + + @property + def insert_string(self) -> str: + return str( + f""" + INSERT INTO `UserGameIdents` ( + `UserId`, `GameServerId`, `Ident`, `CreatedAt`, `LastModifiedAt` + ) VALUES ( + {self._user.id}, + '{self._game_server.id}', + '{self._ident}', + '{self._created_at}', + '{self._modified_at}' + ); + """ + ) + + @property + def udpate_string(self) -> str: + return str( + f""" + UPDATE `UserGameIdents` + SET `LastModifiedAt` = '{self._modified_at}' + WHERE `Id` = {self._id}; + """ + ) + + @property + def delete_string(self) -> str: + return str( + f""" + DELETE FROM `UserGameIdents` + WHERE `Id` = {self._id}; + """ + ) + + @staticmethod + def delete_by_user_id_string(id: int) -> str: + return str( + f""" + DELETE FROM `UserGameIdents` + WHERE `UserId` = {id} + """ + ) diff --git a/kdb-bot/src/bot_data/service/user_game_ident_repository_service.py b/kdb-bot/src/bot_data/service/user_game_ident_repository_service.py new file mode 100644 index 00000000..5967d78b --- /dev/null +++ b/kdb-bot/src/bot_data/service/user_game_ident_repository_service.py @@ -0,0 +1,111 @@ +from typing import Optional + +from cpl_core.database.context import DatabaseContextABC +from cpl_query.extension import List + +from bot_core.logging.database_logger import DatabaseLogger +from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC +from bot_data.abc.user_game_ident_repository_abc import ( + UserGameIdentRepositoryABC, +) +from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.user_game_ident import UserGameIdent + + +class UserGameIdentRepositoryService(UserGameIdentRepositoryABC): + def __init__( + self, + logger: DatabaseLogger, + db_context: DatabaseContextABC, + users: UserRepositoryABC, + game_servers: GameServerRepositoryABC, + ): + self._logger = logger + self._context = db_context + + self._users = users + self._game_servers = game_servers + + UserGameIdentRepositoryABC.__init__(self) + + def _from_result(self, result: tuple) -> UserGameIdent: + return UserGameIdent( + self._users.get_user_by_id(result[1]), + self._game_servers.get_game_server_by_id(result[2]), + result[3], + result[4], + result[5], + id=result[0], + ) + + def get_user_game_idents(self) -> List[UserGameIdent]: + joins = List(UserGameIdent) + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.get_select_all_string()}", + ) + results = self._context.select(UserGameIdent.get_select_all_string()) + for result in results: + self._logger.trace(__name__, f"Get UserGameIdent with id {result[0]}") + joins.append(self._from_result(result)) + + return joins + + def get_user_game_ident_by_id(self, id: int) -> UserGameIdent: + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.get_select_by_id_string(id)}", + ) + result = self._context.select(UserGameIdent.get_select_by_id_string(id))[0] + return self._from_result(result) + + def get_user_game_ident_by_ident(self, ident: str) -> UserGameIdent: + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.get_select_by_ident_string(ident)}", + ) + result = self._context.select(UserGameIdent.get_select_by_ident_string(ident))[0] + return self._from_result(result) + + def find_user_game_ident_by_ident(self, ident: str) -> Optional[UserGameIdent]: + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.get_select_by_ident_string(ident)}", + ) + result = self._context.select(UserGameIdent.get_select_by_ident_string(ident)) + if len(result) == 0: + return None + + result = result[0] + return self._from_result(result) + + def get_user_game_idents_by_user_id(self, user_id: int) -> List[UserGameIdent]: + joins = List(UserGameIdent) + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.get_select_by_user_id_string(user_id)}", + ) + results = self._context.select(UserGameIdent.get_select_by_user_id_string(user_id)) + for result in results: + joins.append(self._from_result(result)) + + return joins + + def add_user_game_ident(self, user_game_ident: UserGameIdent): + self._logger.trace(__name__, f"Send SQL command: {user_game_ident.insert_string}") + self._context.cursor.execute(user_game_ident.insert_string) + + def update_user_game_ident(self, user_game_ident: UserGameIdent): + self._logger.trace(__name__, f"Send SQL command: {user_game_ident.udpate_string}") + self._context.cursor.execute(user_game_ident.udpate_string) + + def delete_user_game_ident(self, user_game_ident: UserGameIdent): + self._logger.trace(__name__, f"Send SQL command: {user_game_ident.delete_string}") + self._context.cursor.execute(user_game_ident.delete_string) + + def delete_user_game_ident_by_user_id(self, user_id: int): + self._logger.trace( + __name__, + f"Send SQL command: {UserGameIdent.delete_by_user_id_string}", + ) + self._context.cursor.execute(UserGameIdent.delete_by_user_id_string(user_id)) diff --git a/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py b/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py index a166ce55..e9ded8ba 100644 --- a/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py +++ b/kdb-bot/src/bot_data/service/user_joined_game_server_repository_service.py @@ -57,14 +57,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): f"Send SQL command: {UserJoinedGameServer.get_select_by_id_string(id)}", ) result = self._context.select(UserJoinedGameServer.get_select_by_id_string(id))[0] - return UserJoinedGameServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0], - ) + return self._from_result(result) def get_user_joined_game_servers_by_user_id(self, user_id: int) -> List[UserJoinedGameServer]: joins = List(UserJoinedGameServer) @@ -74,16 +67,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): ) results = self._context.select(UserJoinedGameServer.get_select_by_user_id_string(user_id)) for result in results: - joins.append( - UserJoinedGameServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0], - ) - ) + joins.append(self._from_result(result)) return joins @@ -93,14 +77,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): f"Send SQL command: {UserJoinedGameServer.get_select_by_user_id_string(user_id)}", ) result = self._context.select(UserJoinedGameServer.get_select_active_by_user_id_string(user_id))[0] - return UserJoinedGameServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0], - ) + return self._from_result(result) def find_active_user_joined_game_server_by_user_id(self, user_id: int) -> Optional[UserJoinedGameServer]: self._logger.trace( @@ -113,14 +90,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): result = result[0] - return UserJoinedGameServer( - self._users.get_user_by_id(result[1]), - result[2], - result[3], - result[4], - result[5], - id=result[0], - ) + return self._from_result(result) def find_active_user_joined_game_servers_by_user_id(self, user_id: int) -> List[Optional[UserJoinedGameServer]]: self._logger.trace( @@ -131,16 +101,7 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC): db_results = self._context.select(UserJoinedGameServer.get_select_active_by_user_id_string(user_id)) for db_result in db_results: - result.append( - UserJoinedGameServer( - self._users.get_user_by_id(db_result[1]), - db_result[2], - db_result[3], - db_result[4], - db_result[5], - id=db_result[0], - ) - ) + result.append(self._from_result(db_result)) return result diff --git a/kdb-bot/src/bot_graphql/model/user.gql b/kdb-bot/src/bot_graphql/model/user.gql index ee8b27cb..37d84b00 100644 --- a/kdb-bot/src/bot_graphql/model/user.gql +++ b/kdb-bot/src/bot_graphql/model/user.gql @@ -3,7 +3,6 @@ type User implements TableQuery { discordId: String name: String xp: Int - minecraftId: String ontime: Float level: Level @@ -28,7 +27,6 @@ input UserFilter { discordId: String name: String xp: Int - minecraftId: String ontime: Float level: LevelFilter server: ServerFilter diff --git a/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql b/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql index 6c4659a2..90475043 100644 --- a/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql +++ b/kdb-bot/src/bot_graphql/model/userJoinedGameServer.gql @@ -20,9 +20,9 @@ input UserJoinedGameServerFilter { type UserJoinedGameServerMutation { userJoined(input: UserJoinedGameServerInput!): UserJoinedGameServer - userLeaved(input: UserJoinedGameServerInput!): UserJoinedGameServer + userLeft(input: UserJoinedGameServerInput!): UserJoinedGameServer } input UserJoinedGameServerInput { - userId: ID! + ident: String! } \ No newline at end of file diff --git a/kdb-bot/src/bot_graphql/mutations/user_joined_game_server_mutation.py b/kdb-bot/src/bot_graphql/mutations/user_joined_game_server_mutation.py index f3ef07f1..0f68ed53 100644 --- a/kdb-bot/src/bot_graphql/mutations/user_joined_game_server_mutation.py +++ b/kdb-bot/src/bot_graphql/mutations/user_joined_game_server_mutation.py @@ -11,6 +11,7 @@ from bot_api.configuration.authentication_settings import AuthenticationSettings from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC from bot_data.abc.user_joined_game_server_repository_abc import UserJoinedGameServerRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC from bot_data.model.api_key import ApiKey @@ -32,6 +33,7 @@ class UserJoinedGameServerMutation(QueryABC): user_joined_game_servers: UserJoinedGameServerRepositoryABC, api_keys: ApiKeyRepositoryABC, game_servers: GameServerRepositoryABC, + user_game_idents: UserGameIdentRepositoryABC, bot: DiscordBotServiceABC, db: DatabaseContextABC, permissions: PermissionService, @@ -46,13 +48,14 @@ class UserJoinedGameServerMutation(QueryABC): self._user_joined_game_servers = user_joined_game_servers self._api_keys = api_keys self._game_servers = game_servers + self._user_game_idents = user_game_idents self._bot = bot self._db = db self._permissions = permissions self._auth_settings = auth_settings self.set_field("userJoined", self.resolve_user_joined) - self.set_field("userLeaved", self.resolve_user_leaved) + self.set_field("userLeft", self.resolve_user_left) def _get_api_key_str(self, api_key: ApiKey) -> str: return hashlib.sha256( @@ -72,7 +75,14 @@ class UserJoinedGameServerMutation(QueryABC): ) def resolve_user_joined(self, *_, input: dict): - user = self._users.get_user_by_id(input["userId"]) + api_key = self._get_api_key() + if api_key is None: + self._logger.warn(__name__, f"UserJoinedGameServer not saved. Api-Key not available!") + return + + game_server = self._game_servers.get_game_server_by_api_key_id(api_key.id) + game_ident = self._user_game_idents.get_user_game_ident_by_ident(input["ident"]) + user = game_ident.user self._can_user_mutate_data(user.server, UserRoleEnum.admin) active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.id) @@ -83,21 +93,27 @@ class UserJoinedGameServerMutation(QueryABC): ) return - api_key = self._get_api_key() - game_server = self._game_servers.get_game_server_by_api_key_id(api_key.id) new = UserJoinedGameServer(user, game_server, datetime.now()) self._user_joined_game_servers.add_user_joined_game_server(new) self._db.save_changes() return self._user_joined_game_servers.get_active_user_joined_game_server_by_user_id(user.id) - def resolve_user_leaved(self, *_, input: dict): - user = self._users.get_user_by_id(input["userId"]) + def resolve_user_left(self, *_, input: dict): + api_key = self._get_api_key() + if api_key is None: + self._logger.warn(__name__, f"UserJoinedGameServer not saved. Api-Key not available!") + return + + game_ident = self._user_game_idents.find_user_game_ident_by_ident(input["ident"]) + if game_ident is None: + return + user = game_ident.user self._can_user_mutate_data(user.server, UserRoleEnum.admin) active = self._user_joined_game_servers.find_active_user_joined_game_server_by_user_id(user.id) if active is None: - return None + return active.leaved_on = datetime.now() settings: BaseServerSettings = self._base_helper.get_config(user.server.discord_id) diff --git a/kdb-bot/src/bot_graphql/queries/user_query.py b/kdb-bot/src/bot_graphql/queries/user_query.py index 857d668d..d9439981 100644 --- a/kdb-bot/src/bot_graphql/queries/user_query.py +++ b/kdb-bot/src/bot_graphql/queries/user_query.py @@ -38,7 +38,6 @@ class UserQuery(DataQueryABC): self.set_field("discordId", self.resolve_discord_id) self.set_field("name", self.resolve_name) self.set_field("xp", self.resolve_xp) - self.set_field("minecraftId", self.resolve_minecraft_id) self.set_field("ontime", self.resolve_ontime) self.set_field("level", self.resolve_level) self.add_collection( @@ -75,10 +74,6 @@ class UserQuery(DataQueryABC): def resolve_xp(user: User, *_): return user.xp - @staticmethod - def resolve_minecraft_id(user: User, *_): - return user.minecraft_id - @staticmethod def resolve_ontime(user: User, *_): return user.ontime diff --git a/kdb-bot/src/modules/base/command/register_group.py b/kdb-bot/src/modules/base/command/register_group.py index e7d9c7cf..dc3fed15 100644 --- a/kdb-bot/src/modules/base/command/register_group.py +++ b/kdb-bot/src/modules/base/command/register_group.py @@ -1,9 +1,12 @@ +from typing import List as TList + import discord import requests from cpl_core.database.context import DatabaseContextABC from cpl_discord.command import DiscordCommandABC from cpl_discord.service import DiscordBotServiceABC from cpl_translation import TranslatePipe +from discord import app_commands from discord.ext import commands from discord.ext.commands import Context @@ -11,8 +14,11 @@ from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger +from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC +from bot_data.model.user_game_ident import UserGameIdent class RegisterGroup(DiscordCommandABC): @@ -24,6 +30,8 @@ class RegisterGroup(DiscordCommandABC): client_utils: ClientUtilsABC, servers: ServerRepositoryABC, users: UserRepositoryABC, + game_server: GameServerRepositoryABC, + user_game_ident: UserGameIdentRepositoryABC, db: DatabaseContextABC, t: TranslatePipe, ): @@ -35,6 +43,8 @@ class RegisterGroup(DiscordCommandABC): self._client_utils = client_utils self._servers = servers self._users = users + self._game_server = game_server + self._user_game_ident = user_game_ident self._db = db self._t = t @@ -49,7 +59,7 @@ class RegisterGroup(DiscordCommandABC): @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def minecraft(self, ctx: Context, member: discord.Member, name: str): + async def minecraft(self, ctx: Context, member: discord.Member, game_server: int, name: str): self._logger.debug(__name__, f"Received command register minecraft {ctx}") minecraft_id = None @@ -74,8 +84,10 @@ class RegisterGroup(DiscordCommandABC): server = self._servers.get_server_by_discord_id(ctx.guild.id) user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) - user.minecraft_id = minecraft_id - self._users.update_user(user) + gs = self._game_server.get_game_server_by_id(game_server) + + game_ident = UserGameIdent(user, gs, minecraft_id) + self._user_game_ident.add_user_game_ident(game_ident) self._db.save_changes() await self._message_service.send_interaction_msg( @@ -83,3 +95,15 @@ class RegisterGroup(DiscordCommandABC): ) self._logger.trace(__name__, f"Finished register minecraft command") + + @minecraft.autocomplete("game_server") + async def game_server_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: + server = self._servers.get_server_by_discord_id(interaction.guild.id) + game_servers = self._game_server.get_game_servers_by_server_id(server.id) + + return [ + app_commands.Choice(name=gs.name, value=gs.id) + for gs in self._client_utils.get_auto_complete_list(game_servers, current, lambda x: x.name) + ] diff --git a/kdb-bot/src/modules/base/command/unregister_group.py b/kdb-bot/src/modules/base/command/unregister_group.py index c9c1282d..4d5f796a 100644 --- a/kdb-bot/src/modules/base/command/unregister_group.py +++ b/kdb-bot/src/modules/base/command/unregister_group.py @@ -1,8 +1,11 @@ +from typing import List as TList + import discord from cpl_core.database.context import DatabaseContextABC from cpl_discord.command import DiscordCommandABC from cpl_discord.service import DiscordBotServiceABC from cpl_translation import TranslatePipe +from discord import app_commands from discord.ext import commands from discord.ext.commands import Context @@ -10,7 +13,9 @@ from bot_core.abc.client_utils_abc import ClientUtilsABC from bot_core.abc.message_service_abc import MessageServiceABC from bot_core.helper.command_checks import CommandChecks from bot_core.logging.command_logger import CommandLogger +from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC from bot_data.abc.server_repository_abc import ServerRepositoryABC +from bot_data.abc.user_game_ident_repository_abc import UserGameIdentRepositoryABC from bot_data.abc.user_repository_abc import UserRepositoryABC @@ -23,6 +28,8 @@ class UnregisterGroup(DiscordCommandABC): client_utils: ClientUtilsABC, servers: ServerRepositoryABC, users: UserRepositoryABC, + game_server: GameServerRepositoryABC, + user_game_idents: UserGameIdentRepositoryABC, db: DatabaseContextABC, t: TranslatePipe, ): @@ -34,26 +41,29 @@ class UnregisterGroup(DiscordCommandABC): self._client_utils = client_utils self._servers = servers self._users = users + self._game_server = game_server + self._user_game_idents = user_game_idents self._db = db self._t = t self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}") - @commands.hybrid_group() - @commands.guild_only() - async def unregister(self, ctx: Context): - pass + # @commands.hybrid_group() + # @commands.guild_only() + # async def unregister(self, ctx: Context): + # pass - @unregister.command() + @commands.hybrid_command() @commands.guild_only() @CommandChecks.check_is_ready() @CommandChecks.check_is_member_moderator() - async def minecraft(self, ctx: Context, member: discord.Member): - self._logger.debug(__name__, f"Received command register minecraft {ctx}") + async def unregister(self, ctx: Context, member: discord.Member, game_server: int): + self._logger.debug(__name__, f"Received command unregister {ctx}") server = self._servers.get_server_by_discord_id(ctx.guild.id) user = self._users.get_user_by_discord_id_and_server_id(member.id, server.id) - user.minecraft_id = None + ident = user.game_idents.where(lambda x: x.game_server.id == game_server).single() + self._user_game_idents.delete_user_game_ident(ident) self._users.update_user(user) self._db.save_changes() @@ -61,4 +71,16 @@ class UnregisterGroup(DiscordCommandABC): ctx.interaction, self._t.transform("modules.base.unregister.success") ) - self._logger.trace(__name__, f"Finished register minecraft command") + self._logger.trace(__name__, f"Finished unregister command") + + @unregister.autocomplete("game_server") + async def game_server_autocomplete( + self, interaction: discord.Interaction, current: str + ) -> TList[app_commands.Choice[str]]: + server = self._servers.get_server_by_discord_id(interaction.guild.id) + game_servers = self._game_server.get_game_servers_by_server_id(server.id) + + return [ + app_commands.Choice(name=gs.name, value=gs.id) + for gs in self._client_utils.get_auto_complete_list(game_servers, current, lambda x: x.name) + ]