#238 #242

Merged
edraft merged 5 commits from #238 into 1.0.0 2023-03-06 08:42:22 +01:00
12 changed files with 339 additions and 36 deletions
Showing only changes of commit 91b2cf7546 - Show all commits

View File

@ -147,6 +147,23 @@
"base": {
"afk_command_channel_missing_message": "Zu unfähig einem Sprachkanal beizutreten?",
"afk_command_move_message": "Ich verschiebe dich ja schon... (◔_◔)",
"game_server": {
"error": {
"nothing_found": "Keine Level Einträge gefunden."
edraft marked this conversation as resolved Outdated
"nothing_found": "Keine Leveleinträge gefunden."
```json "nothing_found": "Keine Leveleinträge gefunden." ```
},
"list": {
"title": "Gameserver",
"description": "Konfigurierte Gameserver:",
"name": "Name",
"api_key": "API Key"
},
"add": {
"success": "Gameserver {} wurde hinzugefügt :)"
},
"remove": {
"success": "Gameserver wurde entfernt :D"
}
},
"goodbye_message": "Schade, dass du uns so schnell verlässt :(",
"info": {
"description": "Informationen über mich",

View File

@ -0,0 +1,39 @@
from abc import ABC, abstractmethod
from cpl_query.extension import List
from bot_data.model.game_server import GameServer
class GameServerRepositoryABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def get_game_servers(self) -> List[GameServer]:
pass
@abstractmethod
def get_game_server_by_id(self, id: int) -> GameServer:
pass
@abstractmethod
def get_game_servers_by_server_id(self, id: int) -> List[GameServer]:
pass
@abstractmethod
def get_game_server_by_api_key_id(self, id: int) -> GameServer:
pass
@abstractmethod
def add_game_server(self, game_server: GameServer):
pass
@abstractmethod
def update_game_server(self, game_server: GameServer):
pass
@abstractmethod
def delete_game_server(self, game_server: GameServer):
pass

View File

@ -11,6 +11,10 @@ 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

View File

@ -9,6 +9,7 @@ from bot_data.abc.api_key_repository_abc import ApiKeyRepositoryABC
from bot_data.abc.auth_user_repository_abc import AuthUserRepositoryABC
from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC
from bot_data.abc.client_repository_abc import ClientRepositoryABC
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
@ -26,6 +27,7 @@ from bot_data.service.api_key_repository_service import ApiKeyRepositoryService
from bot_data.service.auth_user_repository_service import AuthUserRepositoryService
from bot_data.service.auto_role_repository_service import AutoRoleRepositoryService
from bot_data.service.client_repository_service import ClientRepositoryService
from bot_data.service.game_server_repository_service import GameServerRepositoryService
from bot_data.service.known_user_repository_service import KnownUserRepositoryService
from bot_data.service.level_repository_service import LevelRepositoryService
from bot_data.service.seeder_service import SeederService
@ -68,5 +70,6 @@ class DataModule(ModuleABC):
UserMessageCountPerHourRepositoryABC,
UserMessageCountPerHourRepositoryService,
)
services.add_transient(GameServerRepositoryABC, GameServerRepositoryService)
services.add_transient(SeederService)

View File

@ -57,7 +57,7 @@ class GameServer(TableABC):
def get_select_all_string() -> str:
return str(
f"""
SELECT * FROM `GameServer`;
SELECT * FROM `GameServers`;
"""
)
@ -65,16 +65,34 @@ class GameServer(TableABC):
def get_select_by_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `GameServer`
SELECT * FROM `GameServers`
WHERE `Id` = {id};
"""
)
@staticmethod
def get_select_by_api_key_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `GameServers`
WHERE `ApiKeyId` = {id};
"""
)
@staticmethod
def get_select_by_server_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `GameServers`
WHERE `ServerId` = {id};
"""
)
@staticmethod
def get_select_by_user_id_string(id: int) -> str:
return str(
f"""
SELECT * FROM `GameServer`
SELECT * FROM `GameServers`
WHERE `UserId` = {id};
"""
)
@ -83,8 +101,8 @@ class GameServer(TableABC):
def insert_string(self) -> str:
return str(
f"""
INSERT INTO `GameServer` (
`Name`, `ServerId`, `ApiKeyId`, CreatedAt`, `LastModifiedAt`
INSERT INTO `GameServers` (
`Name`, `ServerId`, `ApiKeyId`, `CreatedAt`, `LastModifiedAt`
) VALUES (
'{self._name}',
{self._server.id},
@ -99,7 +117,7 @@ class GameServer(TableABC):
def udpate_string(self) -> str:
return str(
f"""
UPDATE `GameServer`
UPDATE `GameServers`
SET `LastModifiedAt` = '{self._modified_at}'
edraft marked this conversation as resolved Outdated

Ist das so richtig, dass nur "LastModifiedAt" geupdatet wird und keine weitere Variable?

Ist das so richtig, dass nur "LastModifiedAt" geupdatet wird und keine weitere Variable?

Alles andere soll read only sein.
Jedoch möchte ich das schnell ändern können.

Alles andere soll read only sein. Jedoch möchte ich das schnell ändern können.
WHERE `Id` = {self._id};
"""
@ -109,7 +127,7 @@ class GameServer(TableABC):
def delete_string(self) -> str:
return str(
f"""
DELETE FROM `GameServer`
DELETE FROM `GameServers`
WHERE `Id` = {self._id};
"""
)
@ -118,7 +136,7 @@ class GameServer(TableABC):
def delete_by_user_id_string(id: int) -> str:
return str(
f"""
DELETE FROM `GameServer`
DELETE FROM `GameServers`
WHERE `UserId` = {id}
"""
)

View File

@ -0,0 +1,89 @@
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.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.model.game_server import GameServer
class GameServerRepositoryService(GameServerRepositoryABC):
def __init__(
self,
logger: DatabaseLogger,
db_context: DatabaseContextABC,
servers: ServerRepositoryABC,
api_keys: ApiKeyRepositoryABC,
):
self._logger = logger
self._context = db_context
self._servers = servers
self._api_keys = api_keys
GameServerRepositoryABC.__init__(self)
def _from_result(self, result: tuple):
return GameServer(
result[1],
self._servers.get_server_by_id(result[2]),
self._api_keys.get_api_key_by_id(result[3]),
result[4],
result[5],
id=result[0],
)
def get_game_servers(self) -> List[GameServer]:
game_servers = List(GameServer)
self._logger.trace(
__name__,
f"Send SQL command: {GameServer.get_select_all_string()}",
)
results = self._context.select(GameServer.get_select_all_string())
for result in results:
self._logger.trace(__name__, f"Get user-joined-game-server with id {result[0]}")
game_servers.append(self._from_result(result))
return game_servers
def get_game_servers_by_server_id(self, id: int) -> List[GameServer]:
game_servers = List(GameServer)
self._logger.trace(
__name__,
f"Send SQL command: {GameServer.get_select_by_server_id_string(id)}",
)
results = self._context.select(GameServer.get_select_by_server_id_string(id))
for result in results:
self._logger.trace(__name__, f"Get user-joined-game-server with id {result[0]}")
game_servers.append(self._from_result(result))
return game_servers
def get_game_server_by_id(self, id: int) -> GameServer:
self._logger.trace(
__name__,
f"Send SQL command: {GameServer.get_select_by_id_string(id)}",
)
result = self._context.select(GameServer.get_select_by_id_string(id))[0]
return self._from_result(result)
def get_game_server_by_api_key_id(self, id: int) -> GameServer:
self._logger.trace(
__name__,
f"Send SQL command: {GameServer.get_select_by_api_key_id_string(id)}",
)
result = self._context.select(GameServer.get_select_by_api_key_id_string(id))[0]
return self._from_result(result)
def add_game_server(self, game_server: GameServer):
self._logger.trace(__name__, f"Send SQL command: {game_server.insert_string}")
self._context.cursor.execute(game_server.insert_string)
def update_game_server(self, game_server: GameServer):
self._logger.trace(__name__, f"Send SQL command: {game_server.udpate_string}")
self._context.cursor.execute(game_server.udpate_string)
def delete_game_server(self, game_server: GameServer):
self._logger.trace(__name__, f"Send SQL command: {game_server.delete_string}")
self._context.cursor.execute(game_server.delete_string)

View File

@ -4,13 +4,11 @@ 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.api_key_repository_abc import ApiKeyRepositoryABC
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.game_server_repository_abc import GameServerRepositoryABC
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.game_server import GameServer
from bot_data.model.user_joined_game_server import UserJoinedGameServer
@ -20,38 +18,20 @@ class UserJoinedGameServerRepositoryService(UserJoinedGameServerRepositoryABC):
logger: DatabaseLogger,
db_context: DatabaseContextABC,
users: UserRepositoryABC,
servers: ServerRepositoryABC,
api_keys: ApiKeyRepositoryABC,
game_servers: GameServerRepositoryABC,
):
self._logger = logger
self._context = db_context
self._users = users
self._servers = servers
self._api_keys = api_keys
self._game_servers = game_servers
UserJoinedGameServerRepositoryABC.__init__(self)
def _game_server_from_id(self, id: int):
self._logger.trace(
__name__,
f"Send SQL command: {GameServer.get_select_by_id_string(id)}",
)
result = self._context.select(GameServer.get_select_by_id_string(id))[0]
return GameServer(
result[1],
self._servers.get_server_by_id(result[2]),
self._api_keys.get_api_key_by_id(result[3]),
result[4],
result[5],
id=result[0],
)
def _from_result(self, result: tuple) -> UserJoinedGameServer:
return UserJoinedGameServer(
self._users.get_user_by_id(result[1]),
self._game_server_from_id(result[2]),
self._game_servers.get_game_server_by_id(result[2]),
result[3],
result[4],
result[5],

View File

@ -82,7 +82,7 @@ class QueryABC(ObjectType):
break
elif type(element) == AutoRoleRule:
element: AutoRole = element.auto_role
element: AutoRole = element.game_server
for u in user.users:
u: User = u
guild = bot.get_guild(u.server.discord_id)

View File

@ -57,7 +57,7 @@ class AutoRoleRuleFilter(FilterABC):
query = query.where(get_role_name)
if self._auto_role is not None:
auto_roles = self._auto_role.filter(query.select(lambda x: x.auto_role)).select(lambda x: x.id)
query = query.where(lambda x: x.auto_role.id in auto_roles)
auto_roles = self._auto_role.filter(query.select(lambda x: x.game_server)).select(lambda x: x.id)
query = query.where(lambda x: x.game_server.id in auto_roles)
return query

View File

@ -22,7 +22,7 @@ class UserJoinedGameServerQuery(DataQueryABC):
@staticmethod
def resolve_game_server(x: UserJoinedGameServer, *_):
return x.game_server
return x.game_server.name
@staticmethod
def resolve_user(x: UserJoinedGameServer, *_):

View File

@ -8,6 +8,7 @@ from bot_core.abc.module_abc import ModuleABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from modules.base.abc.base_helper_abc import BaseHelperABC
from modules.base.command.afk_command import AFKCommand
from modules.base.command.game_server_group import GameServerGroup
from modules.base.command.help_command import HelpCommand
from modules.base.command.info_command import InfoCommand
from modules.base.command.mass_move_command import MassMoveCommand
@ -66,6 +67,7 @@ class BaseModule(ModuleABC):
self._dc.add_command(UserGroup)
self._dc.add_command(RegisterGroup)
self._dc.add_command(UnregisterGroup)
self._dc.add_command(GameServerGroup)
# events
self._dc.add_event(DiscordEventTypesEnum.on_command.value, BaseOnCommandEvent)
self._dc.add_event(DiscordEventTypesEnum.on_command_error.value, BaseOnCommandErrorEvent)

View File

@ -0,0 +1,151 @@
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
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.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.model.game_server import GameServer
from modules.permission.abc.permission_service_abc import PermissionServiceABC
class GameServerGroup(DiscordCommandABC):
def __init__(
self,
logger: CommandLogger,
message_service: MessageServiceABC,
bot: DiscordBotServiceABC,
client_utils: ClientUtilsABC,
translate: TranslatePipe,
servers: ServerRepositoryABC,
game_servers: GameServerRepositoryABC,
api_keys: ApiKeyRepositoryABC,
db: DatabaseContextABC,
permission_service: PermissionServiceABC,
):
DiscordCommandABC.__init__(self)
self._logger = logger
self._message_service = message_service
self._bot = bot
self._client_utils = client_utils
self._t = translate
self._servers = servers
self._game_servers = game_servers
self._api_keys = api_keys
self._db = db
self._permissions = permission_service
self._logger.trace(__name__, f"Loaded command service: {type(self).__name__}")
@commands.hybrid_group(name="game-server")
@commands.guild_only()
async def game_server(self, ctx: Context):
pass
@game_server.command(alias="game-servers")
@commands.guild_only()
@CommandChecks.check_is_ready()
@CommandChecks.check_is_member_moderator()
async def list(self, ctx: Context, wait: int = None):
self._logger.debug(__name__, f"Received command game_server list {ctx}")
if ctx.guild is None:
return
server = self._servers.get_server_by_discord_id(ctx.guild.id)
game_servers = self._game_servers.get_game_servers_by_server_id(server.id)
if game_servers.count() < 1:
await self._message_service.send_ctx_msg(
ctx, self._t.transform("modules.base.game_server.error.nothing_found")
)
self._logger.trace(__name__, f"Finished command game_server list")
return
game_server_name = ""
api_key = ""
for game_server in game_servers:
game_server: GameServer = game_server
game_server_name += f"\n{game_server.name}"
api_key += f"\n{game_server.api_key.identifier}"
embed = discord.Embed(
title=self._t.transform("modules.base.game_server.list.title"),
description=self._t.transform("modules.base.game_server.list.description"),
color=int("ef9d0d", 16),
)
embed.add_field(
name=self._t.transform("modules.base.game_server.list.name"),
value=game_server_name,
inline=True,
)
embed.add_field(name=self._t.transform("modules.base.game_server.list.api_key"), value=api_key, inline=True)
await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait)
self._logger.trace(__name__, f"Finished command game_server list")
@game_server.command()
@commands.guild_only()
@CommandChecks.check_is_ready()
@CommandChecks.check_is_member_admin()
async def add(self, ctx: Context, name: str, api_key_id: int):
edraft marked this conversation as resolved Outdated

Was passiert wenn man den selben API-Key nochmal hinzufügt?

Was passiert wenn man den selben API-Key nochmal hinzufügt?

Technishc nicht möglich "CONSTRAINT UC_Identifier_Key UNIQUE (Identifier,Key),"
Dann wird ein entsprechender Fehler geschmissen, der so auch nicht zwangsläufig abgefangen werden müsste. (Command Error handling regelt)

Technishc nicht möglich "CONSTRAINT UC_Identifier_Key UNIQUE (`Identifier`,`Key`)," Dann wird ein entsprechender Fehler geschmissen, der so auch nicht zwangsläufig abgefangen werden müsste. (Command Error handling regelt)
self._logger.debug(__name__, f"Received command game-server add {ctx}: {name} {api_key_id}")
server = self._servers.get_server_by_discord_id(ctx.guild.id)
api_key = self._api_keys.get_api_key_by_id(api_key_id)
game_server = GameServer(name, server, api_key)
self._game_servers.add_game_server(game_server)
self._db.save_changes()
await self._message_service.send_ctx_msg(
ctx,
self._t.transform("modules.base.game_server.add.success").format(name),
)
self._logger.trace(__name__, f"Finished command game-server add")
@add.autocomplete("api_key_id")
async def api_key_id_autocomplete(
self, interaction: discord.Interaction, current: str
) -> TList[app_commands.Choice[str]]:
keys = self._api_keys.get_api_keys()
return [
app_commands.Choice(name=f"{key.identifier}: {key.key}", value=key.id)
for key in self._client_utils.get_auto_complete_list(keys, current, lambda x: x.key)
]
@game_server.command()
@commands.guild_only()
@CommandChecks.check_is_ready()
@CommandChecks.check_is_member_admin()
async def remove(self, ctx: Context, id: int):
self._logger.debug(__name__, f"Received command game-server remove {ctx}: {id}")
game_server = self._game_servers.get_game_server_by_id(id)
self._game_servers.delete_game_server(game_server)
self._db.save_changes()
await self._message_service.send_ctx_msg(ctx, self._t.transform("modules.base.game_server.remove.success"))
self._logger.trace(__name__, f"Finished command game-server remove")
@remove.autocomplete("id")
async def id_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_servers.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)
]