Skip to content

Commit 507a2c2

Browse files
implement: proxy kick by maintenance or network full
1 parent 6f8bd3d commit 507a2c2

File tree

6 files changed

+108
-0
lines changed

6 files changed

+108
-0
lines changed

proxy-shared/src/main/kotlin/app/simplecloud/plugin/proxy/shared/ProxyPlugin.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package app.simplecloud.plugin.proxy.shared
22

33
import app.simplecloud.plugin.proxy.shared.config.YamlConfig
4+
import app.simplecloud.plugin.proxy.shared.config.message.MessageConfig
45
import app.simplecloud.plugin.proxy.shared.config.placeholder.PlaceHolderConfiguration
56
import app.simplecloud.plugin.proxy.shared.config.tablis.TabListConfiguration
67
import app.simplecloud.plugin.proxy.shared.handler.CloudControllerHandler
@@ -13,8 +14,14 @@ open class ProxyPlugin(
1314
val config = YamlConfig(dirPath)
1415
val tabListConfiguration = config.load<TabListConfiguration>("tablist")!!
1516
val placeHolderConfiguration = config.load<PlaceHolderConfiguration>("placeholder")!!
17+
val messagesConfiguration = config.load<MessageConfig>("messages")!!
1618
val cloudControllerHandler = CloudControllerHandler()
1719
val motdLayoutHandler = MotdLayoutHandler(config, this)
1820

1921
var maintenance = true
22+
23+
companion object {
24+
val JOIN_MAINTENANCE_PERMISSION = "simplecloud.proxy.join.maintenance"
25+
val JOIN_FULL_PERMISSION = "simplecloud.proxy.join.full"
26+
}
2027
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package app.simplecloud.plugin.proxy.shared.config.message
2+
3+
import org.spongepowered.configurate.objectmapping.ConfigSerializable
4+
5+
@ConfigSerializable
6+
data class KickMessageConfig(
7+
val networkMaintenance: String = "<red>The network is currently in maintenance mode. Please try again later.",
8+
val networkFull: String = "<red>The network is currently full. Please try again later.",
9+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package app.simplecloud.plugin.proxy.shared.config.message
2+
3+
import org.spongepowered.configurate.objectmapping.ConfigSerializable
4+
5+
@ConfigSerializable
6+
data class MessageConfig(
7+
var kickMessage: KickMessageConfig = KickMessageConfig(),
8+
)

proxy-shared/src/main/kotlin/app/simplecloud/plugin/proxy/shared/handler/CloudControllerHandler.kt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,34 @@ class CloudControllerHandler {
7575
} ?: logger.warning("Group name is not initialized.")
7676
}
7777

78+
suspend fun getOnlinePlayersInGroup(): Int {
79+
return groupName?.let {
80+
try {
81+
controllerApi.getServers().getServersByGroup(it).sumBy { it.playerCount.toInt() }
82+
} catch (e: Exception) {
83+
logger.severe("Error retrieving online players in group: ${e.message}")
84+
0
85+
}
86+
} ?: run {
87+
logger.warning("Group name is not initialized.")
88+
0
89+
}
90+
}
91+
92+
suspend fun getMaxPlayersInGroup(): Int {
93+
return groupName?.let {
94+
try {
95+
controllerApi.getGroups().getGroupByName(it).maxPlayers.toInt()
96+
} catch (e: Exception) {
97+
logger.severe("Error retrieving max players in group: ${e.message}")
98+
0
99+
}
100+
} ?: run {
101+
logger.warning("Group name is not initialized.")
102+
0
103+
}
104+
}
105+
78106
private suspend fun retrievePropertyOrEmpty(retrieve: suspend () -> String?): String {
79107
return try {
80108
retrieve() ?: ""

proxy-velocity/src/main/kotlin/app/simplecloud/plugin/proxy/velocity/ProxyVelocityPlugin.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import app.simplecloud.plugin.proxy.velocity.handler.TabListHandler
1111
import app.simplecloud.plugin.proxy.velocity.listener.CloudListener
1212
import app.simplecloud.plugin.proxy.velocity.listener.ConfigureTagResolversListener
1313
import app.simplecloud.plugin.proxy.velocity.listener.ProxyPingListener
14+
import app.simplecloud.plugin.proxy.velocity.listener.ServerPreConnectListener
1415
import com.google.inject.Inject
1516
import com.velocitypowered.api.command.RawCommand
1617
import com.velocitypowered.api.command.SimpleCommand
@@ -42,12 +43,14 @@ class ProxyVelocityPlugin @Inject constructor(
4243
fun onProxyInitialize(event: ProxyInitializeEvent) {
4344
config.save("tablist", this.tabListConfiguration)
4445
config.save("placeholder", this.placeHolderConfiguration)
46+
config.save("messages", this.messagesConfiguration)
4547

4648
this.motdLayoutHandler.loadMotdLayouts()
4749

4850
this.proxyServer.eventManager.register(this, ProxyPingListener(this))
4951
this.proxyServer.eventManager.register(this, ConfigureTagResolversListener(this))
5052
this.proxyServer.eventManager.register(this, CloudListener(this))
53+
this.proxyServer.eventManager.register(this, ServerPreConnectListener(this))
5154

5255
if (this.tabListConfiguration.tabListUpdateTime > 0)
5356
this.tabListHandler.startTabListTask()
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package app.simplecloud.plugin.proxy.velocity.listener
2+
3+
import app.simplecloud.plugin.proxy.shared.ProxyPlugin
4+
import app.simplecloud.plugin.proxy.velocity.ProxyVelocityPlugin
5+
import com.velocitypowered.api.event.PostOrder
6+
import com.velocitypowered.api.event.Subscribe
7+
import com.velocitypowered.api.event.player.ServerPreConnectEvent
8+
import com.velocitypowered.api.proxy.Player
9+
import kotlinx.coroutines.runBlocking
10+
import java.util.logging.Logger
11+
12+
class ServerPreConnectListener(
13+
private val proxyPlugin: ProxyVelocityPlugin,
14+
) {
15+
private val logger = Logger.getLogger(ServerPreConnectListener::class.java.name)
16+
17+
@Subscribe(order = PostOrder.EARLY)
18+
fun handle(event: ServerPreConnectEvent) {
19+
val player = event.player
20+
21+
if (proxyPlugin.maintenance && !player.hasPermission(ProxyPlugin.JOIN_MAINTENANCE_PERMISSION)) {
22+
denyAccess(
23+
player,
24+
this.proxyPlugin.messagesConfiguration.kickMessage.networkMaintenance,
25+
event
26+
)
27+
return
28+
}
29+
30+
runBlocking {
31+
try {
32+
if (!isServerFull(player)) {
33+
return@runBlocking
34+
}
35+
denyAccess(player, proxyPlugin.messagesConfiguration.kickMessage.networkFull, event)
36+
} catch (e: Exception) {
37+
logger.severe("Error checking player limits: ${e.message}")
38+
}
39+
}
40+
}
41+
42+
private suspend fun isServerFull(player: Player): Boolean {
43+
val maxPlayers = proxyPlugin.cloudControllerHandler.getMaxPlayersInGroup()
44+
val onlinePlayers = proxyPlugin.cloudControllerHandler.getOnlinePlayersInGroup()
45+
46+
return onlinePlayers >= maxPlayers && !player.hasPermission(ProxyPlugin.JOIN_FULL_PERMISSION)
47+
}
48+
49+
private fun denyAccess(player: Player, message: String, event: ServerPreConnectEvent) {
50+
player.disconnect(proxyPlugin.deserializeToComponent(message, player))
51+
event.result = ServerPreConnectEvent.ServerResult.denied()
52+
}
53+
}

0 commit comments

Comments
 (0)