Skip to content
This repository was archived by the owner on Dec 10, 2025. It is now read-only.

Commit cd81c6f

Browse files
committed
feat(proxy): implement multi-proxy support for load balancing and scalability
1 parent 17ee47c commit cd81c6f

File tree

49 files changed

+556
-157
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+556
-157
lines changed

surf-cloud-api/surf-cloud-api-client/surf-cloud-api-client-velocity/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dev.slne.surf.surfapi.gradle.util.slneReleases
22

33
plugins {
4-
id("dev.slne.surf.surfapi.gradle.core")
4+
id("dev.slne.surf.surfapi.gradle.velocity")
55
}
66

77
dependencies {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package dev.slne.surf.cloud.api.client.velocity.server
2+
3+
import com.velocitypowered.api.proxy.ProxyServer
4+
import dev.slne.surf.cloud.api.common.server.CloudServer
5+
import kotlin.jvm.optionals.getOrNull
6+
7+
fun CloudServer.toRegisteredServer(proxy: ProxyServer) =
8+
proxy.getServer(name).getOrNull() ?: error("Server $name is not registered in Velocity proxy")

surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/meta/SurfNettyPacket.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ object DefaultIds {
126126
const val CLIENTBOUND_CLEAR_RESOURCE_PACKS_PACKET = "cloud:clientbound:clear_resource_packs"
127127

128128
const val PLAYER_CONNECT_TO_SERVER_PACKET = "cloud:player:connect_to_server"
129+
const val PLAYER_CONNECTED_TO_SERVER_PACKET = "cloud:player:connected_to_server"
129130
const val PLAYER_DISCONNECT_FROM_SERVER_PACKET = "cloud:player:disconnect_from_server"
130131

131132
const val SERVERBOUND_REQUEST_DISPLAY_NAME_PACKET = "cloud:serverbound:request_display_name"

surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/netty/packet/NettyPacket.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ abstract class NettyPacket {
1717
* This is for internal use and is not intended to be modified externally.
1818
*/
1919
@InternalApi
20+
@Transient
2021
var handled = false
2122
private set
2223

@@ -33,40 +34,48 @@ abstract class NettyPacket {
3334
* is required after this packet and the protocol switches to the next state.
3435
*/
3536
@InternalApi
37+
@Transient
3638
open val terminal: Boolean = false
3739
// endregion
3840

41+
@Transient
3942
private val meta = this::class.getPacketMeta()
4043

4144
/**
4245
* The unique identifier of this packet.
4346
*/
47+
@Transient
4448
val id = meta.id
4549

4650
/**
4751
* The flow direction of this packet (e.g., client-to-server or server-to-client).
4852
*/
53+
@Transient
4954
val flow = meta.flow
5055

5156
/**
5257
* Supported protocols for this packet.
5358
*/
59+
@Transient
5460
val protocols = meta.protocols
5561

5662
/**
5763
* A session identifier for the packet, generated randomly for each instance.
5864
*/
65+
@Transient
5966
val sessionId = ThreadLocalRandom.current().nextLong()
6067

6168
/**
6269
* Indicates whether the packet is skippable.
6370
* If true, the packet will be ignored if its size exceeds the allowed limit.
6471
*/
72+
@Transient
6573
open val skippable = false
6674

6775
/**
6876
* Additional packets that should be sent after this packet, if any.
6977
*/
78+
@Transient
7079
open val extraPackets: List<NettyPacket>? = null
7180

7281
/**

surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/server/CloudServer.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package dev.slne.surf.cloud.api.common.server
33
import dev.slne.surf.cloud.api.common.player.CloudPlayer
44
import dev.slne.surf.cloud.api.common.player.ConnectionResultEnum
55
import it.unimi.dsi.fastutil.objects.ObjectList
6-
import net.kyori.adventure.text.Component
76
import org.jetbrains.annotations.ApiStatus
87
import org.jetbrains.annotations.Unmodifiable
98

@@ -25,5 +24,7 @@ interface CloudServer : CommonCloudServer {
2524
*/
2625
val allowlist: Boolean
2726

27+
val lobby: Boolean
28+
2829
suspend fun pullPlayers(players: Collection<CloudPlayer>): @Unmodifiable ObjectList<Pair<CloudPlayer, ConnectionResultEnum>>
2930
}

surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/server/CloudServerManager.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ interface CloudServerManager {
7070

7171
suspend fun retrieveAllServers(): ObjectCollection<out CommonCloudServer>
7272

73+
suspend fun retrieveServers(): ObjectCollection<out CloudServer>
74+
suspend fun retrieveProxies(): ObjectCollection<out ProxyCloudServer>
75+
7376
suspend fun pullPlayersToGroup(
7477
group: String,
7578
players: Collection<CloudPlayer>

surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/server/CommonCloudServer.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMap
77
import net.kyori.adventure.audience.ForwardingAudience
88
import net.kyori.adventure.text.Component
99
import org.jetbrains.annotations.ApiStatus
10+
import java.net.InetSocketAddress
1011

1112
/**
1213
* Represents the result of a batch transfer operation.
@@ -73,6 +74,8 @@ interface CommonCloudServer : ForwardingAudience {
7374
*/
7475
val users: UserList
7576

77+
val playAddress: InetSocketAddress
78+
7679
val displayName: String
7780
get() = "$group/$uid $name"
7881

surf-cloud-api/surf-cloud-api-server/src/main/kotlin/dev/slne/surf/cloud/api/server/netty/packet/NettyPacketServerExtensions.kt

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,8 @@ package dev.slne.surf.cloud.api.server.netty.packet
22

33
import dev.slne.surf.cloud.api.common.netty.packet.NettyPacket
44
import dev.slne.surf.cloud.api.server.server.ServerCloudServerManager
5-
import dev.slne.surf.surfapi.core.api.util.logger
65

7-
private val log = logger()
86

9-
suspend fun NettyPacket.broadcast() {
10-
ServerCloudServerManager.retrieveAllServers().forEach { server ->
11-
try {
12-
server.connection.send(this)
13-
} catch (e: Throwable) {
14-
log.atWarning()
15-
.withCause(e)
16-
.log("Failed to send packet in broadcast action to server ${server.displayName}")
17-
}
18-
}
7+
fun NettyPacket.broadcast() {
8+
ServerCloudServerManager.broadcast(this)
199
}

surf-cloud-api/surf-cloud-api-server/src/main/kotlin/dev/slne/surf/cloud/api/server/server/ServerCloudServerManager.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.slne.surf.cloud.api.server.server
22

3+
import dev.slne.surf.cloud.api.common.netty.packet.NettyPacket
34
import dev.slne.surf.cloud.api.common.server.CloudServerManager
45
import dev.slne.surf.cloud.api.common.server.CommonCloudServer
56
import it.unimi.dsi.fastutil.objects.ObjectCollection
@@ -20,6 +21,10 @@ interface ServerCloudServerManager : CloudServerManager {
2021
override suspend fun retrieveServersInGroup(group: String): ObjectList<out ServerCommonCloudServer>
2122
override suspend fun retrieveServersByCategory(category: String): ObjectList<out ServerCommonCloudServer>
2223
override suspend fun retrieveAllServers(): ObjectCollection<out ServerCommonCloudServer>
24+
override suspend fun retrieveServers(): ObjectCollection<out ServerCloudServer>
25+
override suspend fun retrieveProxies(): ObjectCollection<out ServerProxyCloudServer>
26+
27+
fun broadcast(packet: NettyPacket)
2328

2429
companion object :
2530
ServerCloudServerManager by CloudServerManager.instance as ServerCloudServerManager

surf-cloud-bukkit/src/main/kotlin/dev/slne/surf/cloud/bukkit/BukkitMain.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ import net.kyori.adventure.text.format.NamedTextColor
1818
import org.bukkit.Location
1919
import org.bukkit.entity.Player
2020
import org.bukkit.event.server.ServerLoadEvent
21+
import java.net.DatagramSocket
22+
import java.net.InetSocketAddress
23+
import java.net.URI
2124
import kotlin.contracts.ExperimentalContracts
2225
import kotlin.contracts.contract
2326

@@ -43,6 +46,21 @@ class BukkitMain : SuspendingJavaPlugin() {
4346
serverLoaded = true
4447

4548
launch {
49+
val datagramSocketIp = DatagramSocket().run {
50+
connect(InetSocketAddress("8.8.8.8", 53))
51+
val ip = localAddress.hostAddress
52+
close()
53+
ip
54+
}
55+
56+
val publicIp = URI("https://checkip.amazonaws.com").toURL().readText().trim()
57+
58+
repeat(20) {
59+
println("Ip: ${server.ip}")
60+
println("Public IP: $publicIp")
61+
println("Datagram Socket IP: $datagramSocketIp")
62+
}
63+
4664
try {
4765
coreCloudInstance.afterStart()
4866
} catch (t: Throwable) {

0 commit comments

Comments
 (0)