Skip to content

Commit f762c69

Browse files
authored
feat(proxy): hand a bare /region on a lobby to the lobby's world map (#75)
/region <code> still transfers. Without a code, a player on a lobby now gets the lobby's map dialog for picking the default region: hasPermission declines that one case, and Velocity forwards a declined command to the current server. On any other server the bare command still lists the regions. Lobbies are recognised by GROUNDS_LOBBY_SERVER_PREFIX (default "lobby"), the prefix plugin-lobby uses.
1 parent adf0ccd commit f762c69

3 files changed

Lines changed: 59 additions & 1 deletion

File tree

‎velocity/src/main/kotlin/gg/grounds/proxy/velocity/GroundsProxyPlugin.kt‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,20 @@ constructor(private val proxy: ProxyServer, private val logger: Logger) {
166166
// Looked up per invocation rather than captured: the registry is written during startup and
167167
// a reference taken now could be the one from before another plugin registered.
168168
val service = { ProxyServiceRegistry.get(ProxyService::class.java) }
169+
// The same prefix plugin-lobby uses to tell lobbies from other backends.
170+
val lobbyServerPrefix =
171+
System.getenv("GROUNDS_LOBBY_SERVER_PREFIX")?.trim()?.takeIf(String::isNotEmpty)
172+
?: "lobby"
169173
val region = { RegionCatalog.currentCode() }
170174
proxy.commandManager.register("online", OnlineCommand(service))
171-
proxy.commandManager.register("region", RegionCommand(catalog, region, service))
175+
proxy.commandManager.register(
176+
"region",
177+
RegionCommand(catalog, region, service) { player ->
178+
player.currentServer
179+
.map { it.serverInfo.name.startsWith(lobbyServerPrefix, ignoreCase = true) }
180+
.orElse(false)
181+
},
182+
)
172183

173184
// How many players each server holds, answered to a backend that asks. Registered here
174185
// rather than in the lobby's own plugin because the number only exists on this side:

‎velocity/src/main/kotlin/gg/grounds/proxy/velocity/command/RegionCommand.kt‎

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,27 @@ import net.kyori.adventure.text.format.NamedTextColor
1717
*
1818
* Geo-steering already puts a player in the nearest region; this is the override — for playing with
1919
* someone on the other side of the world, or for testing a region deliberately.
20+
*
21+
* A bare `/region` from a player on a lobby is not answered here: the lobby draws a world map for
22+
* picking the default region, and Velocity hands a command the proxy declines in [hasPermission] to
23+
* the player's current server. Everywhere else the bare command still lists the regions.
2024
*/
2125
class RegionCommand(
2226
private val catalog: RegionCatalog,
2327
private val currentRegion: () -> String?,
2428
private val proxyService: () -> ProxyService?,
29+
private val isOnLobby: (Player) -> Boolean = { false },
2530
) : SimpleCommand {
2631

32+
override fun hasPermission(invocation: SimpleCommand.Invocation): Boolean {
33+
val player = invocation.source() as? Player
34+
return regionAnswersHere(
35+
isPlayer = player != null,
36+
hasArguments = invocation.arguments().isNotEmpty(),
37+
onLobby = player != null && isOnLobby(player),
38+
)
39+
}
40+
2741
override fun execute(invocation: SimpleCommand.Invocation) {
2842
val source = invocation.source()
2943
val player = source as? Player
@@ -98,3 +112,14 @@ class RegionCommand(
98112
return catalog.codes.filter { it.lowercase().startsWith(typed) }
99113
}
100114
}
115+
116+
/**
117+
* Whether the proxy handles a `/region`. Only a player's bare command on a lobby is declined, which
118+
* makes Velocity forward it to the lobby's world map. Top level so a test can reach it without the
119+
* Velocity API, which is compile-only.
120+
*/
121+
internal fun regionAnswersHere(
122+
isPlayer: Boolean,
123+
hasArguments: Boolean,
124+
onLobby: Boolean,
125+
): Boolean = !isPlayer || hasArguments || !onLobby
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package gg.grounds.proxy.velocity
2+
3+
import gg.grounds.proxy.velocity.command.regionAnswersHere
4+
import org.junit.jupiter.api.Assertions.assertFalse
5+
import org.junit.jupiter.api.Assertions.assertTrue
6+
import org.junit.jupiter.api.Test
7+
8+
class RegionCommandTest {
9+
10+
/** Declining is what makes Velocity forward the command to the lobby's world map. */
11+
@Test
12+
fun `a bare region on a lobby goes to the lobby`() {
13+
assertFalse(regionAnswersHere(isPlayer = true, hasArguments = false, onLobby = true))
14+
}
15+
16+
@Test
17+
fun `a region code, another server or the console stays on the proxy`() {
18+
assertTrue(regionAnswersHere(isPlayer = true, hasArguments = true, onLobby = true))
19+
assertTrue(regionAnswersHere(isPlayer = true, hasArguments = false, onLobby = false))
20+
assertTrue(regionAnswersHere(isPlayer = false, hasArguments = false, onLobby = false))
21+
}
22+
}

0 commit comments

Comments
 (0)