Skip to content

Commit 4c7c19b

Browse files
YosephOmX
authored andcommitted
Prepare clients for localized lobby notices
The server change introduces optional notice localization metadata while preserving legacy text. This updates the shared lobby contract first so downstream clients can adopt the fields without raw JSON handling. Constraint: FAF server PR 1083 adds optional notice localization fields while keeping legacy text for existing clients. Rejected: Client-only parsing workaround | shared lobby API should model the server contract first. Confidence: high Scope-risk: narrow Directive: Keep the two-argument NoticeInfo constructor available for Java callers until client consumers migrate. Tested: JAVA_HOME=/Users/yoseph/Codexperiment/.deps/jdk21/Contents/Home ./gradlew :lobby:test --tests com.faforever.commons.lobby.ServerMessageTest Tested: git diff --check Not-tested: Full Gradle suite. Co-authored-by: OmX <omx@oh-my-codex.dev>
1 parent 50328af commit 4c7c19b

2 files changed

Lines changed: 35 additions & 2 deletions

File tree

lobby/src/main/kotlin/com/faforever/commons/lobby/ConnectionApi.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
66
import com.fasterxml.jackson.annotation.JsonValue
77
import reactor.core.publisher.Flux
88
import reactor.core.publisher.Mono
9+
import java.time.OffsetDateTime
910

1011
/**
1112
* API to manage connection to the Lobby server
@@ -49,9 +50,15 @@ internal class InvalidResponse : ServerMessage
4950
* A general message from the server (automated or broadcast from admin) to display to the user.
5051
* FIXME: Should maybe offer event codes for translations in case of automated responses.
5152
*/
52-
data class NoticeInfo(
53+
data class NoticeInfo @JvmOverloads constructor(
5354
val style: String?,
5455
val text: String?,
56+
@JsonProperty("i18n_key")
57+
val i18nKey: String? = null,
58+
@JsonProperty("i18n_args")
59+
val i18nArgs: List<String> = emptyList(),
60+
@JsonProperty("expires_at")
61+
val expiresAt: OffsetDateTime? = null,
5562
) : ServerMessage
5663

5764
/**
@@ -210,4 +217,3 @@ internal class ClientPingMessage : ClientMessage
210217
* Holds no data, just checks if the connection is still alive
211218
*/
212219
internal class ClientPongMessage : ClientMessage
213-

lobby/src/test/kotlin/com/faforever/commons/lobby/ServerMessageTest.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,33 @@ class ServerMessageTest {
101101
assertEquals(NoticeInfo("kill", "boo"), result)
102102
}
103103

104+
@Test
105+
fun deserializeLocalizableNoticeInfo() {
106+
val result = objectMapper.readValue<ServerMessage>(
107+
"""
108+
{
109+
"command": "notice",
110+
"style": "error",
111+
"text": "You are banned from FAF until 2026-05-10T22:00:00+00:00. Reason: test",
112+
"i18n_key": "login.error.banned",
113+
"i18n_args": ["2026-05-10T22:00:00+00:00", "test"],
114+
"expires_at": "2026-05-10T22:00:00+00:00"
115+
}
116+
""".trimIndent()
117+
)
118+
119+
assertEquals(
120+
NoticeInfo(
121+
"error",
122+
"You are banned from FAF until 2026-05-10T22:00:00+00:00. Reason: test",
123+
"login.error.banned",
124+
listOf("2026-05-10T22:00:00+00:00", "test"),
125+
OffsetDateTime.parse("2026-05-10T22:00:00+00:00")
126+
),
127+
result
128+
)
129+
}
130+
104131
@Test
105132
fun deserializeGameJoinFailed() {
106133
val result = objectMapper.readValue<ServerMessage>(

0 commit comments

Comments
 (0)