From 0f1cbb58675247ad9a291a8701e68a2ac02ad8fa Mon Sep 17 00:00:00 2001 From: dinhkien0701 <24021540@vnu.edu.vn> Date: Tue, 12 May 2026 20:56:37 +0700 Subject: [PATCH 1/3] Add localizable metadata to ban notice --- server/exceptions.py | 20 +++++++++++++++++--- server/lobbyconnection.py | 10 +++++++--- tests/integration_tests/test_login.py | 16 ++++++++++++++-- tests/integration_tests/test_server.py | 8 +++++++- 4 files changed, 45 insertions(+), 9 deletions(-) diff --git a/server/exceptions.py b/server/exceptions.py index ff7a7cc57..7854332bf 100644 --- a/server/exceptions.py +++ b/server/exceptions.py @@ -6,6 +6,9 @@ from server.timing import datetime_now +BAN_NOTICE_I18N_KEY = "notice.ban" +BAN_APPEAL_EMAIL = "moderation@faforever.com" + class ClientError(Exception): """ @@ -31,12 +34,23 @@ def __init__(self, ban_expiry, ban_reason, *args, **kwargs): self.ban_expiry = ban_expiry self.ban_reason = ban_reason + def localization(self): + return { + "i18n_key": BAN_NOTICE_I18N_KEY, + "i18n_args": { + "duration": self._ban_duration_text(), + "reason": self.ban_reason, + "appeal_email": BAN_APPEAL_EMAIL + } + } + def message(self): + data = self.localization()["i18n_args"] return ( - f"You are banned from FAF {self._ban_duration_text()}.
" - f"Reason:
{self.ban_reason}

" + f"You are banned from FAF {data['duration']}.
" + f"Reason:
{data['reason']}

" "If you would like to appeal this ban, please send an email to: " - "moderation@faforever.com" + f"{data['appeal_email']}" ) def _ban_duration_text(self): diff --git a/server/lobbyconnection.py b/server/lobbyconnection.py index 5b5ec2e10..476a2eff0 100644 --- a/server/lobbyconnection.py +++ b/server/lobbyconnection.py @@ -222,12 +222,16 @@ async def on_message_received(self, message): "text": e.message }) except BanError as e: - await self.send({ + ban_notice = { "command": "notice", "style": "error", - "text": e.message() + "text": e.message(), + **e.localization() + } + await self.send({ + **ban_notice }) - await self.abort(e.message()) + await self.abort(ban_notice["text"]) except ClientError as e: self._logger.warning( "ClientError[%s]: %s", diff --git a/tests/integration_tests/test_login.py b/tests/integration_tests/test_login.py index 0d7c5c843..2a631ad32 100644 --- a/tests/integration_tests/test_login.py +++ b/tests/integration_tests/test_login.py @@ -45,7 +45,13 @@ async def test_server_ban(lobby_server, user): "You are banned from FAF forever.
Reason:
Test permanent ban" "

If you would like to appeal this ban, please send an " "email to: moderation@faforever.com" - ) + ), + "i18n_key": "notice.ban", + "i18n_args": { + "duration": "forever", + "reason": "Test permanent ban", + "appeal_email": "moderation@faforever.com" + } } @@ -80,7 +86,13 @@ async def test_server_ban_token(lobby_server, user, jwk_priv_key, jwk_kid): "You are banned from FAF forever.
Reason:
Test permanent ban" "

If you would like to appeal this ban, please send an " "email to: moderation@faforever.com" - ) + ), + "i18n_key": "notice.ban", + "i18n_args": { + "duration": "forever", + "reason": "Test permanent ban", + "appeal_email": "moderation@faforever.com" + } } diff --git a/tests/integration_tests/test_server.py b/tests/integration_tests/test_server.py index ae00663bb..fe4f9ccf2 100644 --- a/tests/integration_tests/test_server.py +++ b/tests/integration_tests/test_server.py @@ -852,7 +852,13 @@ async def test_server_ban_prevents_hosting(lobby_server, database, command): "You are banned from FAF forever.
Reason:
Test live ban
" "
If you would like to appeal this ban, please send an email " "to: moderation@faforever.com" - ) + ), + "i18n_key": "notice.ban", + "i18n_args": { + "duration": "forever", + "reason": "Test live ban", + "appeal_email": "moderation@faforever.com" + } } From 6baab4c9b0a957803462bc4f5e2a86265c56778b Mon Sep 17 00:00:00 2001 From: dinhkien0701 <24021540@vnu.edu.vn> Date: Tue, 12 May 2026 21:34:36 +0700 Subject: [PATCH 2/3] Fix mypy arg type in QDataStream pack_message --- server/protocol/qdatastream.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/protocol/qdatastream.py b/server/protocol/qdatastream.py index 999d2313c..6adea3227 100644 --- a/server/protocol/qdatastream.py +++ b/server/protocol/qdatastream.py @@ -92,7 +92,7 @@ def pack_message(*args: str) -> bytes: raise NotImplementedError("Only string serialization is supported") msg += QDataStreamProtocol.pack_qstring(arg) - return QDataStreamProtocol.pack_block(msg) + return QDataStreamProtocol.pack_block(bytes(msg)) @staticmethod def encode_message(message: dict) -> bytes: From 7ab837e568da5cbd3a38995a6852ce4de773a1aa Mon Sep 17 00:00:00 2001 From: dinhkien0701 <24021540@vnu.edu.vn> Date: Tue, 12 May 2026 21:45:59 +0700 Subject: [PATCH 3/3] Update Pipfile.lock hash for pipenv verify --- Pipfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Pipfile.lock b/Pipfile.lock index 615d5a42b..91020093f 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "67adacda446396d91de50fe41c426c738226113aa0b3e3f16a00f2141ff7bc8a" + "sha256": "a187fb4a62ec0cc2dab78542af7c21eb559388bac49e0f84f35f656aa1e19200" }, "pipfile-spec": 6, "requires": {