Skip to content

Commit 5a1adc6

Browse files
feat: enhance Velocity support and unify configuration/events system
- Add `VelocityMain` implementation with server lifecycle event support. - Introduce `SurfPlayerEventListener` for Velocity to manage player connection/disconnection caching. - Add player argument parsing with `SurfPlayerArgument` and `SurfOfflinePlayerArgument`. - Move `SurfServerConfig` and `SurfServerConfigHolder` to the core module for shared use across platforms. - Adjust `networkListCommand` to sort players by `lastKnownName` in ascending order. - Introduce utility extensions for easier `Player` to `SurfPlayer` conversions in Velocity.
1 parent 5044aed commit 5a1adc6

File tree

10 files changed

+222
-11
lines changed

10 files changed

+222
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package dev.slne.surf.core.api.velocity.command.argument
2+
3+
import com.mojang.brigadier.arguments.StringArgumentType
4+
import com.mojang.brigadier.context.CommandContext
5+
import dev.jorel.commandapi.CommandAPICommand
6+
import dev.jorel.commandapi.CommandTree
7+
import dev.jorel.commandapi.arguments.Argument
8+
import dev.jorel.commandapi.arguments.CommandAPIArgumentType
9+
import dev.jorel.commandapi.executors.CommandArguments
10+
import dev.slne.surf.core.api.common.player.SurfPlayer
11+
import dev.slne.surf.core.api.common.surfCoreApi
12+
import dev.slne.surf.surfapi.core.api.util.logger
13+
import kotlinx.coroutines.*
14+
import kotlinx.coroutines.future.asDeferred
15+
import kotlinx.coroutines.future.future
16+
17+
@Suppress("UNCHECKED_CAST")
18+
open class SurfOfflinePlayerArgument(nodeName: String) :
19+
Argument<Deferred<SurfPlayer?>>(nodeName, StringArgumentType.string()) {
20+
override fun getPrimitiveType(): Class<Deferred<SurfPlayer?>> {
21+
return Deferred::class.java as Class<Deferred<SurfPlayer?>>
22+
}
23+
24+
override fun getArgumentType(): CommandAPIArgumentType? {
25+
return CommandAPIArgumentType.PRIMITIVE_STRING
26+
}
27+
28+
override fun <Source> parseArgument(
29+
cmdCtx: CommandContext<Source>,
30+
key: String,
31+
previousArgs: CommandArguments,
32+
): Deferred<SurfPlayer?> = scope.future {
33+
surfCoreApi.getOfflinePlayer(StringArgumentType.getString(cmdCtx, key))
34+
}.asDeferred()
35+
36+
companion object {
37+
private val log = logger()
38+
private val scope =
39+
CoroutineScope(Dispatchers.IO + CoroutineName("SurfOfflinePlayerArgument") + CoroutineExceptionHandler { _, throwable ->
40+
log.atWarning()
41+
.withCause(throwable)
42+
.log("An error occurred in SurfOfflinePlayerArgument")
43+
})
44+
}
45+
}
46+
47+
inline fun CommandTree.surfOfflinePlayerArgument(
48+
nodeName: String,
49+
optional: Boolean = false,
50+
block: Argument<*>.() -> Unit = {}
51+
): CommandTree = then(
52+
SurfOfflinePlayerArgument(nodeName).setOptional(optional).apply(block)
53+
)
54+
55+
inline fun Argument<*>.surfOfflinePlayerArgument(
56+
nodeName: String,
57+
optional: Boolean = false,
58+
block: Argument<*>.() -> Unit = {}
59+
): Argument<*> = then(
60+
SurfOfflinePlayerArgument(nodeName).setOptional(optional).apply(block)
61+
)
62+
63+
inline fun CommandAPICommand.surfOfflinePlayerArgument(
64+
nodeName: String,
65+
optional: Boolean = false,
66+
block: Argument<*>.() -> Unit = {}
67+
): CommandAPICommand =
68+
withArguments(SurfOfflinePlayerArgument(nodeName).setOptional(optional).apply(block))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package dev.slne.surf.core.api.velocity.command.argument
2+
3+
import com.mojang.brigadier.arguments.StringArgumentType
4+
import com.mojang.brigadier.context.CommandContext
5+
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType
6+
import com.velocitypowered.api.command.VelocityBrigadierMessage
7+
import dev.jorel.commandapi.CommandAPICommand
8+
import dev.jorel.commandapi.CommandTree
9+
import dev.jorel.commandapi.arguments.Argument
10+
import dev.jorel.commandapi.arguments.CommandAPIArgumentType
11+
import dev.jorel.commandapi.executors.CommandArguments
12+
import dev.slne.surf.core.api.common.player.SurfPlayer
13+
import dev.slne.surf.core.api.common.surfCoreApi
14+
import dev.slne.surf.surfapi.core.api.messages.adventure.buildText
15+
16+
open class SurfPlayerArgument(nodeName: String) :
17+
Argument<SurfPlayer>(nodeName, StringArgumentType.string()) {
18+
override fun getPrimitiveType(): Class<SurfPlayer> {
19+
return SurfPlayer::class.java
20+
}
21+
22+
override fun getArgumentType(): CommandAPIArgumentType? {
23+
return CommandAPIArgumentType.PRIMITIVE_STRING
24+
}
25+
26+
override fun <Source> parseArgument(
27+
cmdCtx: CommandContext<Source>,
28+
key: String,
29+
previousArgs: CommandArguments,
30+
): SurfPlayer = surfCoreApi.getPlayer(StringArgumentType.getString(cmdCtx, key))
31+
?: throw SimpleCommandExceptionType(
32+
VelocityBrigadierMessage.tooltip(
33+
buildText {
34+
appendPrefix()
35+
error("Der Spieler wurde nicht gefunden.")
36+
}
37+
)
38+
).create()
39+
}
40+
41+
inline fun CommandTree.surfPlayerArgument(
42+
nodeName: String,
43+
optional: Boolean = false,
44+
block: Argument<*>.() -> Unit = {}
45+
): CommandTree = then(
46+
SurfPlayerArgument(nodeName).setOptional(optional).apply(block)
47+
)
48+
49+
inline fun Argument<*>.surfPlayerArgument(
50+
nodeName: String,
51+
optional: Boolean = false,
52+
block: Argument<*>.() -> Unit = {}
53+
): Argument<*> = then(
54+
SurfPlayerArgument(nodeName).setOptional(optional).apply(block)
55+
)
56+
57+
inline fun CommandAPICommand.surfPlayerArgument(
58+
nodeName: String,
59+
optional: Boolean = false,
60+
block: Argument<*>.() -> Unit = {}
61+
): CommandAPICommand =
62+
withArguments(SurfPlayerArgument(nodeName).setOptional(optional).apply(block))
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package dev.slne.surf.core.api.velocity.util
2+
3+
import com.velocitypowered.api.proxy.Player
4+
import dev.slne.surf.core.api.common.surfCoreApi
5+
6+
fun Player.toSurfPlayer() = surfCoreApi.getPlayer(this.uniqueId)
7+
?: error("SurfPlayer for Velocity Player ${this.username} not found!")
8+
9+
val Player.surfPlayer get() = this.toSurfPlayer()

surf-core-paper/src/main/kotlin/dev/slne/surf/core/paper/config/SurfServerConfig.kt renamed to surf-core-core/surf-core-core-common/src/main/kotlin/dev/slne/surf/core/core/common/config/SurfServerConfig.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.slne.surf.core.paper.config
1+
package dev.slne.surf.core.core.common.config
22

33
import org.spongepowered.configurate.objectmapping.ConfigSerializable
44

surf-core-paper/src/main/kotlin/dev/slne/surf/core/paper/config/SurfServerConfigHolder.kt renamed to surf-core-core/surf-core-core-common/src/main/kotlin/dev/slne/surf/core/core/common/config/SurfServerConfigHolder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dev.slne.surf.core.paper.config
1+
package dev.slne.surf.core.core.common.config
22

33
import dev.slne.surf.surfapi.core.api.config.manager.SpongeConfigManager
44
import dev.slne.surf.surfapi.core.api.config.surfConfigApi
@@ -15,6 +15,7 @@ class SurfServerConfigHolder(
1515
dataPath,
1616
"config.yml"
1717
)
18+
1819
configManager = surfConfigApi.getSpongeConfigManagerForConfig(SurfServerConfig::class.java)
1920

2021
this.reload()

surf-core-paper/src/main/kotlin/dev/slne/surf/core/paper/PaperBootstrap.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package dev.slne.surf.core.paper
22

33
import dev.slne.surf.core.api.common.event.SurfServerStartEvent
4+
import dev.slne.surf.core.core.common.config.SurfServerConfigHolder
45
import dev.slne.surf.core.core.common.event.surfEventBus
56
import dev.slne.surf.core.core.common.redis.redisApi
67
import dev.slne.surf.core.core.common.redis.redisLoader
7-
import dev.slne.surf.core.paper.config.SurfServerConfigHolder
88
import dev.slne.surf.core.paper.teleport.TeleportRedisListener
99
import io.papermc.paper.plugin.bootstrap.BootstrapContext
1010
import io.papermc.paper.plugin.bootstrap.PluginBootstrap

surf-core-paper/src/main/kotlin/dev/slne/surf/core/paper/command/NetworkListCommand.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import dev.slne.surf.surfapi.core.api.messages.adventure.sendText
99
fun networkListCommand() = commandTree("nlist") {
1010
withPermission(PermissionRegistry.COMMAND_NETWORK_LIST)
1111
anyExecutor { executor, _ ->
12-
val players = surfPlayerService.players.sortedByDescending { it.lastKnownName }
12+
val players = surfPlayerService.players.sortedBy { it.lastKnownName }
1313

1414
if (players.isEmpty()) {
1515
executor.sendText {

surf-core-paper/src/main/kotlin/dev/slne/surf/core/paper/event/SurfPlayerEventListener.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
package dev.slne.surf.core.paper.event
22

3-
import com.github.shynixn.mccoroutine.folia.launch
43
import dev.slne.surf.core.api.common.event.SurfEventHandler
54
import dev.slne.surf.core.api.common.event.SurfPlayerConnectEvent
65
import dev.slne.surf.core.api.common.event.SurfPlayerDisconnectEvent
76
import dev.slne.surf.core.core.common.player.surfPlayerService
8-
import dev.slne.surf.core.paper.plugin
97

108
object SurfPlayerEventListener {
119
@SurfEventHandler
1210
fun onPlayerConnect(event: SurfPlayerConnectEvent) {
13-
plugin.launch {
14-
surfPlayerService.cachePlayer(event.player)
15-
}
11+
surfPlayerService.cachePlayer(event.player)
1612
}
1713

1814
@SurfEventHandler
Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,61 @@
11
package dev.slne.surf.core.velocity
22

3-
class VelocityMain {
4-
}
3+
import com.github.shynixn.mccoroutine.velocity.SuspendingPluginContainer
4+
import com.google.inject.Inject
5+
import com.velocitypowered.api.event.EventManager
6+
import com.velocitypowered.api.event.Subscribe
7+
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent
8+
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent
9+
import com.velocitypowered.api.plugin.PluginContainer
10+
import com.velocitypowered.api.plugin.PluginManager
11+
import com.velocitypowered.api.plugin.annotation.DataDirectory
12+
import com.velocitypowered.api.proxy.ProxyServer
13+
import dev.slne.surf.core.api.common.event.SurfServerOnlineEvent
14+
import dev.slne.surf.core.api.common.event.SurfServerStartEvent
15+
import dev.slne.surf.core.api.common.event.SurfServerStoppingEvent
16+
import dev.slne.surf.core.core.common.config.SurfServerConfigHolder
17+
import dev.slne.surf.core.core.common.event.surfEventBus
18+
import dev.slne.surf.core.core.common.redis.redisApi
19+
import dev.slne.surf.core.core.common.redis.redisLoader
20+
import dev.slne.surf.core.velocity.listener.SurfPlayerEventListener
21+
import java.nio.file.Path
22+
23+
class VelocityMain @Inject constructor(
24+
val proxy: ProxyServer,
25+
val pluginManager: PluginManager,
26+
val eventManager: EventManager,
27+
@param:DataDirectory val dataPath: Path,
28+
val pluginContainer: PluginContainer,
29+
suspendingPluginContainer: SuspendingPluginContainer
30+
) {
31+
init {
32+
suspendingPluginContainer.initialize(this)
33+
redisLoader.load(dataPath)
34+
redisApi.subscribeToEvents(SurfPlayerEventListener)
35+
redisLoader.connect()
36+
37+
instance = this
38+
surfServerConfigHolder = SurfServerConfigHolder(dataPath)
39+
40+
surfEventBus.fire(SurfServerStartEvent(surfServerConfig.serverName))
41+
}
42+
43+
@Subscribe
44+
fun onProxyInitialize(event: ProxyInitializeEvent) {
45+
surfEventBus.fire(SurfServerOnlineEvent(surfServerConfig.serverName))
46+
}
47+
48+
@Subscribe
49+
fun onProxyShutdown(event: ProxyShutdownEvent) {
50+
surfEventBus.fire(SurfServerStoppingEvent(surfServerConfig.serverName))
51+
}
52+
53+
companion object {
54+
lateinit var instance: VelocityMain
55+
lateinit var surfServerConfigHolder: SurfServerConfigHolder
56+
}
57+
}
58+
59+
val proxy get() = VelocityMain.instance.proxy
60+
val plugin get() = VelocityMain.instance
61+
val surfServerConfig get() = VelocityMain.surfServerConfigHolder.config
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package dev.slne.surf.core.velocity.listener
2+
3+
import dev.slne.surf.core.api.common.event.SurfEventHandler
4+
import dev.slne.surf.core.api.common.event.SurfPlayerConnectEvent
5+
import dev.slne.surf.core.api.common.event.SurfPlayerDisconnectEvent
6+
import dev.slne.surf.core.core.common.player.surfPlayerService
7+
8+
object SurfPlayerEventListener {
9+
@SurfEventHandler
10+
fun onPlayerConnect(event: SurfPlayerConnectEvent) {
11+
surfPlayerService.cachePlayer(event.player)
12+
}
13+
14+
@SurfEventHandler
15+
fun onPlayerDisconnect(event: SurfPlayerDisconnectEvent) {
16+
surfPlayerService.invalidatePlayer(event.player.uuid)
17+
}
18+
}

0 commit comments

Comments
 (0)