Sync
This commit is contained in:
@@ -1,10 +0,0 @@
|
||||
import cc.maxmc.msm.child.misc.SubServer
|
||||
import kotlin.io.path.Path
|
||||
|
||||
suspend fun main() {
|
||||
val server = SubServer(10086, "test", 25571, Path("/Users/tony_all/Servers/MSM/"))
|
||||
server.initServer()
|
||||
server.startServer()
|
||||
Thread.sleep(10000)
|
||||
server.cleanup()
|
||||
}
|
||||
@@ -2,9 +2,10 @@ package cc.maxmc.msm.child
|
||||
|
||||
import cc.maxmc.msm.api.MultiServerManAPIProvider
|
||||
import cc.maxmc.msm.child.api.APIImpl
|
||||
import cc.maxmc.msm.child.api.APIPacketListener
|
||||
import cc.maxmc.msm.child.listener.APIPacketListener
|
||||
import cc.maxmc.msm.child.command.Api
|
||||
import cc.maxmc.msm.child.command.Send
|
||||
import cc.maxmc.msm.child.listener.ProtocolListener
|
||||
import cc.maxmc.msm.child.netty.NetClient
|
||||
import cc.maxmc.msm.child.settings.Settings
|
||||
import cc.maxmc.msm.common.network.netty.NetworkRegistry
|
||||
@@ -21,8 +22,9 @@ class MultiServerMan : Plugin() {
|
||||
ProxyServer.getInstance().pluginManager.registerCommand(this, Send)
|
||||
ProxyServer.getInstance().pluginManager.registerCommand(this, Api)
|
||||
ProxyServer.getInstance().pluginManager.registerListener(this, APIPacketListener)
|
||||
ProxyServer.getInstance().pluginManager.registerListener(this, ProtocolListener)
|
||||
NetworkRegistry
|
||||
NetClient.start(Settings.Parent.address, Settings.Parent.port)
|
||||
NetClient.init(Settings.Parent.address, Settings.Parent.port)
|
||||
}
|
||||
|
||||
override fun onDisable() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package cc.maxmc.msm.child.api
|
||||
|
||||
import cc.maxmc.msm.api.MultiServerManAPI
|
||||
import cc.maxmc.msm.api.misc.ServerInfo
|
||||
import cc.maxmc.msm.api.misc.MatchInfo
|
||||
import cc.maxmc.msm.child.netty.NetClient
|
||||
import cc.maxmc.msm.common.network.packet.PPacketAPICall
|
||||
import java.util.*
|
||||
@@ -13,10 +13,10 @@ object APIImpl : MultiServerManAPI {
|
||||
val apiCallCache = HashMap<UUID, CompletableFuture<in Any>>()
|
||||
private const val TIMEOUT = 3L
|
||||
|
||||
override fun getServer(type: String, players: MutableList<String>): ServerInfo {
|
||||
override fun getServer(type: String, players: MutableList<String>): MatchInfo {
|
||||
val packet = PPacketAPICall.PPacketCallGetServer(type, players)
|
||||
NetClient.sendPacket(packet)
|
||||
val future = CompletableFuture<ServerInfo>()
|
||||
val future = CompletableFuture<MatchInfo>()
|
||||
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||
return future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||
}
|
||||
@@ -30,10 +30,10 @@ object APIImpl : MultiServerManAPI {
|
||||
return
|
||||
}
|
||||
|
||||
override fun getPlayerServer(player: String): ServerInfo {
|
||||
override fun getPlayerServer(player: String): MatchInfo {
|
||||
val packet = PPacketAPICall.PPacketCallGetPlayerServer(player)
|
||||
NetClient.sendPacket(packet)
|
||||
val future = CompletableFuture<ServerInfo>()
|
||||
val future = CompletableFuture<MatchInfo>()
|
||||
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||
return future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||
}
|
||||
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
package cc.maxmc.msm.child.api
|
||||
package cc.maxmc.msm.child.listener
|
||||
|
||||
import cc.maxmc.msm.child.api.APIImpl
|
||||
import cc.maxmc.msm.common.event.PacketReceiveEvent
|
||||
import cc.maxmc.msm.common.network.packet.CPacketAPICallback
|
||||
import cc.maxmc.msm.common.utils.debug
|
||||
import net.md_5.bungee.api.plugin.Listener
|
||||
import net.md_5.bungee.event.EventHandler
|
||||
|
||||
@@ -21,12 +21,12 @@ object APIPacketListener : Listener {
|
||||
}
|
||||
|
||||
is CPacketAPICallback.CPacketCallbackGetPlayerServer -> {
|
||||
future?.complete(packet.serverInfo)
|
||||
future?.complete(packet.matchInfo)
|
||||
?: throw IllegalStateException("Packet callback received, however no request")
|
||||
}
|
||||
|
||||
is CPacketAPICallback.CPacketCallbackGetServer -> {
|
||||
future?.complete(packet.serverInfo)
|
||||
future?.complete(packet.matchInfo)
|
||||
?: throw IllegalStateException("Packet callback received, however no request")
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package cc.maxmc.msm.child.listener
|
||||
|
||||
import cc.maxmc.msm.child.MultiServerMan
|
||||
import cc.maxmc.msm.child.misc.SubServer
|
||||
import cc.maxmc.msm.child.netty.NetClient
|
||||
import cc.maxmc.msm.child.settings.Settings
|
||||
import cc.maxmc.msm.common.event.ChannelInactiveEvent
|
||||
import cc.maxmc.msm.common.event.PacketReceiveEvent
|
||||
import cc.maxmc.msm.common.network.packet.CPacketGetInfo
|
||||
import cc.maxmc.msm.common.network.packet.CPacketRequestServer
|
||||
import cc.maxmc.msm.common.network.packet.PPacketChildInfo
|
||||
import cc.maxmc.msm.common.network.packet.PPacketServerStarted
|
||||
import cc.maxmc.msm.common.utils.log
|
||||
import cc.maxmc.msm.common.utils.pluginScope
|
||||
import kotlinx.coroutines.launch
|
||||
import net.md_5.bungee.api.plugin.Listener
|
||||
import net.md_5.bungee.event.EventHandler
|
||||
import java.util.*
|
||||
import kotlin.io.path.isDirectory
|
||||
import kotlin.io.path.listDirectoryEntries
|
||||
import kotlin.io.path.name
|
||||
|
||||
object ProtocolListener : Listener {
|
||||
val serverCache = HashMap<UUID, SubServer>()
|
||||
|
||||
@EventHandler
|
||||
fun onGetInfo(packetE: PacketReceiveEvent) {
|
||||
if (packetE.packet !is CPacketGetInfo) return
|
||||
val types = MultiServerMan.instance.dataFolder.toPath().resolve("patterns").listDirectoryEntries()
|
||||
.filter { it.isDirectory() }.map { it.name }.toMutableSet()
|
||||
val packetCallBack = PPacketChildInfo(Settings.portRange.toHashSet(), types)
|
||||
NetClient.sendPacket(packetCallBack)
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun onRequestServer(packetE: PacketReceiveEvent) {
|
||||
val packet = packetE.packet as? CPacketRequestServer ?: return
|
||||
val serverInfo = packet.serverInfo
|
||||
val subServer = SubServer(serverInfo.uid, packet.type, serverInfo.server!!.split(":")[1].toInt())
|
||||
pluginScope.launch {
|
||||
subServer.initServer()
|
||||
subServer.startServer()
|
||||
NetClient.sendPacket(PPacketServerStarted(serverInfo))
|
||||
}
|
||||
}
|
||||
|
||||
fun onDisconnect(packet: ChannelInactiveEvent) {
|
||||
repeat(10) {
|
||||
log("Remote Disconnected.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,18 +5,19 @@ import cc.maxmc.msm.child.utils.ScriptRunner
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import kotlin.coroutines.resume
|
||||
import kotlin.coroutines.suspendCoroutine
|
||||
import kotlin.io.path.copyToRecursively
|
||||
import kotlin.io.path.createDirectories
|
||||
import kotlin.io.path.deleteRecursively
|
||||
|
||||
@OptIn(kotlin.io.path.ExperimentalPathApi::class)
|
||||
class SubServer(
|
||||
val id: Int,
|
||||
val type: String,
|
||||
val port: Int,
|
||||
baseFolder: Path = MultiServerMan.instance.dataFolder.toPath()
|
||||
val uid: UUID, val type: String, val port: Int, baseFolder: Path = MultiServerMan.instance.dataFolder.toPath()
|
||||
) {
|
||||
private val serverFolder = baseFolder.resolve("cache").resolve(id.toString()).also { it.createDirectories() }
|
||||
private val serverFolder =
|
||||
baseFolder.resolve("cache").resolve(uid.toString().substring(0..7)).also { it.createDirectories() }
|
||||
private val patternFolder = baseFolder.resolve("pattern").resolve(type).also { it.createDirectories() }
|
||||
private val runner = ScriptRunner(serverFolder.resolve("start.sh"))
|
||||
|
||||
@@ -24,16 +25,15 @@ class SubServer(
|
||||
patternFolder.copyToRecursively(serverFolder, followLinks = false, overwrite = true)
|
||||
}
|
||||
|
||||
fun startServer() {
|
||||
suspend fun startServer() = suspendCoroutine {
|
||||
runner.launch(port.toString())
|
||||
runner.onOutput("For help, type \"help\" or \"?\"") {
|
||||
println("Started.")
|
||||
it.resume(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun cleanup() {
|
||||
runner.exec("stop")
|
||||
println("Exec stop")
|
||||
runner.exit()
|
||||
serverFolder.deleteRecursively()
|
||||
}
|
||||
|
||||
@@ -2,34 +2,45 @@ package cc.maxmc.msm.child.netty
|
||||
|
||||
import cc.maxmc.msm.common.network.BungeePacket
|
||||
import cc.maxmc.msm.common.network.netty.NetworkRegistry
|
||||
import cc.maxmc.msm.common.utils.log
|
||||
import cc.maxmc.msm.common.utils.pipelineInit
|
||||
import cc.maxmc.msm.common.utils.pluginScope
|
||||
import io.netty.bootstrap.Bootstrap
|
||||
import io.netty.channel.Channel
|
||||
import io.netty.channel.ChannelFutureListener
|
||||
import io.netty.channel.ChannelOption
|
||||
import io.netty.channel.nio.NioEventLoopGroup
|
||||
import io.netty.channel.socket.nio.NioSocketChannel
|
||||
import kotlinx.coroutines.*
|
||||
|
||||
object NetClient {
|
||||
private val loop = NioEventLoopGroup()
|
||||
private lateinit var channel: Channel
|
||||
private lateinit var boot: Bootstrap
|
||||
|
||||
fun start(address: String, port: Int) {
|
||||
val future = Bootstrap()
|
||||
.channel(NioSocketChannel::class.java)
|
||||
.group(loop)
|
||||
.handler(pipelineInit(NetworkRegistry.PacketDirection.CHILD_BOUND))
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
fun init(address: String, port: Int) {
|
||||
boot = Bootstrap().channel(NioSocketChannel::class.java).group(loop)
|
||||
.handler(pipelineInit(NetworkRegistry.PacketDirection.CHILD_BOUND)).option(ChannelOption.TCP_NODELAY, true)
|
||||
.remoteAddress(address, port)
|
||||
.connect().addListener(ChannelFutureListener {
|
||||
val result = it.cause() ?: return@ChannelFutureListener println(
|
||||
"§a| §7成功连接到集群的主节点. (${
|
||||
it.channel().remoteAddress()
|
||||
})"
|
||||
)
|
||||
result.printStackTrace()
|
||||
})
|
||||
channel = future.channel()
|
||||
runBlocking {
|
||||
connect(0)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun connect(delay: Long = 3000) {
|
||||
delay(delay)
|
||||
log("§b| §7正在尝试连接主BC")
|
||||
val future = boot.connect().await()
|
||||
val result = future.cause()
|
||||
if (result == null) {
|
||||
channel = future.channel()
|
||||
log("§a| §7成功连接到集群的主节点. (${future.channel().remoteAddress()})")
|
||||
return
|
||||
}
|
||||
log("§c| §7未能连接到主BC,将在 §c3s §7后重新连接。(原因: ${result.message})")
|
||||
withContext(Dispatchers.IO) {
|
||||
connect()
|
||||
}
|
||||
}
|
||||
|
||||
fun sendPacket(packet: BungeePacket) {
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
# 主BC的地址及端口
|
||||
parent:
|
||||
address: 127.0.0.1
|
||||
port: 23333
|
||||
|
||||
# 该子BC所在机器所能开放的端口
|
||||
ports:
|
||||
- 30000
|
||||
- 30001..30019
|
||||
- 30443
|
||||
|
||||
# 该子BC所支持的服务端模版类型及模版类型启动所需参数
|
||||
patterns:
|
||||
main:
|
||||
args: [ "-ListenPort=${port}", "-usr=usr", "-pwd=pwd" ]
|
||||
Reference in New Issue
Block a user