parent
aa4a229b7d
commit
e1459c3e8e
|
|
@ -9,13 +9,13 @@ import java.util.List;
|
||||||
@SuppressWarnings("unused") // API
|
@SuppressWarnings("unused") // API
|
||||||
public interface MultiServerManAPI {
|
public interface MultiServerManAPI {
|
||||||
@NotNull
|
@NotNull
|
||||||
ServerInfo getServer(@NotNull String type, @NotNull List<ProxiedPlayer> players);
|
ServerInfo getServer(@NotNull String type, @NotNull List<String> players);
|
||||||
|
|
||||||
void informEnd(int id);
|
void informEnd(int id);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
ServerInfo getPlayerServer(@NotNull ProxiedPlayer player);
|
ServerInfo getPlayerServer(@NotNull String player);
|
||||||
|
|
||||||
Boolean containPlayer(@NotNull ProxiedPlayer player);
|
Boolean containPlayer(@NotNull String player);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,22 @@
|
||||||
package cc.maxmc.msm.api;
|
package cc.maxmc.msm.api;
|
||||||
|
|
||||||
@SuppressWarnings("unused") // API
|
@SuppressWarnings("unused") // API
|
||||||
public abstract class MultiServerManAPIProvider {
|
public class MultiServerManAPIProvider {
|
||||||
private static MultiServerManAPIProvider instance;
|
private static MultiServerManAPI instance = null;
|
||||||
|
|
||||||
public static MultiServerManAPI getAPI() {
|
public static MultiServerManAPI getAPI() {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
throw new NotLoadedException();
|
throw new NotLoadedException();
|
||||||
}
|
}
|
||||||
return instance.provideAPI();
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract MultiServerManAPI provideAPI();
|
public static void register(MultiServerManAPI api) {
|
||||||
|
if (instance != null) {
|
||||||
|
throw new IllegalStateException("The MultiServerMan API has been load twice");
|
||||||
|
}
|
||||||
|
instance = api;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在加载 API 之前请求 API 时引发异常。
|
* 在加载 API 之前请求 API 时引发异常。
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
package cc.maxmc.msm.child
|
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.command.Api
|
||||||
import cc.maxmc.msm.child.command.Send
|
import cc.maxmc.msm.child.command.Send
|
||||||
import cc.maxmc.msm.child.netty.NetClient
|
import cc.maxmc.msm.child.netty.NetClient
|
||||||
import cc.maxmc.msm.child.settings.Settings
|
import cc.maxmc.msm.child.settings.Settings
|
||||||
|
|
@ -13,7 +17,10 @@ class MultiServerMan : Plugin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
|
MultiServerManAPIProvider.register(APIImpl)
|
||||||
ProxyServer.getInstance().pluginManager.registerCommand(this, Send)
|
ProxyServer.getInstance().pluginManager.registerCommand(this, Send)
|
||||||
|
ProxyServer.getInstance().pluginManager.registerCommand(this, Api)
|
||||||
|
ProxyServer.getInstance().pluginManager.registerListener(this, APIPacketListener)
|
||||||
NetworkRegistry
|
NetworkRegistry
|
||||||
NetClient.start(Settings.Parent.address, Settings.Parent.port)
|
NetClient.start(Settings.Parent.address, Settings.Parent.port)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,44 +4,45 @@ import cc.maxmc.msm.api.MultiServerManAPI
|
||||||
import cc.maxmc.msm.api.misc.ServerInfo
|
import cc.maxmc.msm.api.misc.ServerInfo
|
||||||
import cc.maxmc.msm.child.netty.NetClient
|
import cc.maxmc.msm.child.netty.NetClient
|
||||||
import cc.maxmc.msm.common.network.packet.PPacketAPICall
|
import cc.maxmc.msm.common.network.packet.PPacketAPICall
|
||||||
import net.md_5.bungee.api.connection.ProxiedPlayer
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
object APIImpl : MultiServerManAPI {
|
object APIImpl : MultiServerManAPI {
|
||||||
val apiCallCache = HashMap<UUID, CompletableFuture<out Any>>()
|
val apiCallCache = HashMap<UUID, CompletableFuture<in Any>>()
|
||||||
|
private const val TIMEOUT = 3L
|
||||||
|
|
||||||
override fun getServer(type: String, players: MutableList<ProxiedPlayer>): ServerInfo {
|
override fun getServer(type: String, players: MutableList<String>): ServerInfo {
|
||||||
val packet = PPacketAPICall.PPacketCallGetServer(type, players.map { it.name })
|
val packet = PPacketAPICall.PPacketCallGetServer(type, players)
|
||||||
NetClient.sendPacket(packet)
|
NetClient.sendPacket(packet)
|
||||||
val future = CompletableFuture<ServerInfo>()
|
val future = CompletableFuture<ServerInfo>()
|
||||||
apiCallCache[UUID.randomUUID()] = future
|
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||||
return future.get(1, TimeUnit.SECONDS)
|
return future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun informEnd(id: Int) {
|
override fun informEnd(id: Int) {
|
||||||
val packet = PPacketAPICall.PPacketCallInformEnd(id)
|
val packet = PPacketAPICall.PPacketCallInformEnd(id)
|
||||||
NetClient.sendPacket(packet)
|
NetClient.sendPacket(packet)
|
||||||
val future = CompletableFuture<Unit>()
|
val future = CompletableFuture<Unit>()
|
||||||
apiCallCache[UUID.randomUUID()] = future
|
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||||
future.get(1, TimeUnit.SECONDS)
|
future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlayerServer(player: ProxiedPlayer): ServerInfo {
|
override fun getPlayerServer(player: String): ServerInfo {
|
||||||
val packet = PPacketAPICall.PPacketCallGetPlayerServer(player.name)
|
val packet = PPacketAPICall.PPacketCallGetPlayerServer(player)
|
||||||
NetClient.sendPacket(packet)
|
NetClient.sendPacket(packet)
|
||||||
val future = CompletableFuture<ServerInfo>()
|
val future = CompletableFuture<ServerInfo>()
|
||||||
apiCallCache[UUID.randomUUID()] = future
|
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||||
return future.get(1, TimeUnit.SECONDS)
|
return future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun containPlayer(player: ProxiedPlayer): Boolean {
|
override fun containPlayer(player: String): Boolean {
|
||||||
val packet = PPacketAPICall.PPacketCallContainPlayer(player.name)
|
val packet = PPacketAPICall.PPacketCallContainPlayer(player)
|
||||||
NetClient.sendPacket(packet)
|
NetClient.sendPacket(packet)
|
||||||
val future = CompletableFuture<Boolean>()
|
val future = CompletableFuture<Boolean>()
|
||||||
apiCallCache[UUID.randomUUID()] = future
|
apiCallCache[packet.uid] = future as CompletableFuture<Any>
|
||||||
return future.get(1, TimeUnit.SECONDS)
|
return future.get(TIMEOUT, TimeUnit.SECONDS)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
package cc.maxmc.msm.child.api
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
object APIPacketListener : Listener {
|
||||||
|
@EventHandler
|
||||||
|
fun onPacket(packetEvent: PacketReceiveEvent) {
|
||||||
|
val packet = packetEvent.packet
|
||||||
|
if (packet !is CPacketAPICallback) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val future = APIImpl.apiCallCache[packet.uid]
|
||||||
|
when (packet) {
|
||||||
|
is CPacketAPICallback.CPacketCallbackContainPlayer -> {
|
||||||
|
future?.complete(packet.value)
|
||||||
|
?: throw IllegalStateException("Packet callback received, however no request")
|
||||||
|
}
|
||||||
|
|
||||||
|
is CPacketAPICallback.CPacketCallbackGetPlayerServer -> {
|
||||||
|
future?.complete(packet.serverInfo)
|
||||||
|
?: throw IllegalStateException("Packet callback received, however no request")
|
||||||
|
}
|
||||||
|
|
||||||
|
is CPacketAPICallback.CPacketCallbackGetServer -> {
|
||||||
|
future?.complete(packet.serverInfo)
|
||||||
|
?: throw IllegalStateException("Packet callback received, however no request")
|
||||||
|
}
|
||||||
|
|
||||||
|
is CPacketAPICallback.CPacketCallbackInformEnd -> {
|
||||||
|
future?.complete(Unit)
|
||||||
|
?: throw IllegalStateException("Packet callback received, however no request")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
package cc.maxmc.msm.child.command
|
||||||
|
|
||||||
|
import cc.maxmc.msm.api.MultiServerManAPIProvider
|
||||||
|
import net.md_5.bungee.api.CommandSender
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent
|
||||||
|
import net.md_5.bungee.api.plugin.Command
|
||||||
|
|
||||||
|
object Api : Command("api") {
|
||||||
|
override fun execute(sender: CommandSender, args: Array<out String>) {
|
||||||
|
sender.sendMessage(TextComponent("Calling API"))
|
||||||
|
val api = args[0]
|
||||||
|
val apiInst = MultiServerManAPIProvider.getAPI()
|
||||||
|
@Suppress("IMPLICIT_CAST_TO_ANY") val ret = when (api) {
|
||||||
|
"gs" -> {
|
||||||
|
apiInst.getServer("def", listOf("abc", "def"))
|
||||||
|
}
|
||||||
|
|
||||||
|
"ie" -> {
|
||||||
|
apiInst.informEnd(100)
|
||||||
|
}
|
||||||
|
|
||||||
|
"gps" -> {
|
||||||
|
apiInst.getPlayerServer("def")
|
||||||
|
}
|
||||||
|
|
||||||
|
"cp" -> {
|
||||||
|
apiInst.containPlayer("awa")
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
"non api exist"
|
||||||
|
}
|
||||||
|
}.toString()
|
||||||
|
sender.sendMessage(TextComponent("Returning $ret"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -22,7 +22,12 @@ object NetClient {
|
||||||
.option(ChannelOption.TCP_NODELAY, true)
|
.option(ChannelOption.TCP_NODELAY, true)
|
||||||
.remoteAddress(address, port)
|
.remoteAddress(address, port)
|
||||||
.connect().addListener(ChannelFutureListener {
|
.connect().addListener(ChannelFutureListener {
|
||||||
println("§a| §7成功连接到集群的主节点. (${it.channel().remoteAddress()})")
|
val result = it.cause() ?: return@ChannelFutureListener println(
|
||||||
|
"§a| §7成功连接到集群的主节点. (${
|
||||||
|
it.channel().remoteAddress()
|
||||||
|
})"
|
||||||
|
)
|
||||||
|
result.printStackTrace()
|
||||||
})
|
})
|
||||||
channel = future.channel()
|
channel = future.channel()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,11 @@ object Settings {
|
||||||
val name
|
val name
|
||||||
get() = config
|
get() = config
|
||||||
|
|
||||||
|
val portRange
|
||||||
|
get() = config.getStringList("ports").flatMap {
|
||||||
|
it.toIntOrNull()?.run { listOf(this) } ?: it.split("..").run { this[0].toInt()..this[1].toInt() }
|
||||||
|
}
|
||||||
|
|
||||||
object Parent {
|
object Parent {
|
||||||
val address: String
|
val address: String
|
||||||
get() = config.getString("parent.address", "localhost")
|
get() = config.getString("parent.address", "localhost")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
parent:
|
parent:
|
||||||
address: 127.0.0.1
|
address: 127.0.0.1
|
||||||
port: 23333
|
port: 23333
|
||||||
|
ports:
|
||||||
|
- 30000
|
||||||
|
- 30001..30019
|
||||||
|
-
|
||||||
|
|
@ -9,7 +9,7 @@ import io.netty.channel.SimpleChannelInboundHandler
|
||||||
@Sharable
|
@Sharable
|
||||||
object ClusterPacketHandler : SimpleChannelInboundHandler<BungeePacket>() {
|
object ClusterPacketHandler : SimpleChannelInboundHandler<BungeePacket>() {
|
||||||
override fun channelRead0(ctx: ChannelHandlerContext, msg: BungeePacket) {
|
override fun channelRead0(ctx: ChannelHandlerContext, msg: BungeePacket) {
|
||||||
debug("call event")
|
// debug("call event")
|
||||||
PacketReceiveEvent(ctx.channel(), msg).callEvent()
|
PacketReceiveEvent(ctx.channel(), msg).callEvent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,10 +14,8 @@ class ClusterMsgCodec(private val current: NetworkRegistry.PacketDirection) : By
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(ctx: ChannelHandlerContext, `in`: ByteBuf, out: MutableList<Any>) {
|
override fun decode(ctx: ChannelHandlerContext, `in`: ByteBuf, out: MutableList<Any>) {
|
||||||
debug("decode packet")
|
|
||||||
val id = `in`.readInt()
|
val id = `in`.readInt()
|
||||||
val packet = NetworkRegistry.getPacketByID(current, id)
|
val packet = NetworkRegistry.getPacketByID(current, id)
|
||||||
debug(packet.toString())
|
|
||||||
packet.decode(`in`)
|
packet.decode(`in`)
|
||||||
out.add(packet)
|
out.add(packet)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package cc.maxmc.msm.common.network.netty
|
package cc.maxmc.msm.common.network.netty
|
||||||
|
|
||||||
import cc.maxmc.msm.common.network.BungeePacket
|
import cc.maxmc.msm.common.network.BungeePacket
|
||||||
|
import cc.maxmc.msm.common.network.packet.CPacketAPICallback
|
||||||
import cc.maxmc.msm.common.network.packet.CPacketDebug
|
import cc.maxmc.msm.common.network.packet.CPacketDebug
|
||||||
|
import cc.maxmc.msm.common.network.packet.PPacketAPICall
|
||||||
import cc.maxmc.msm.common.network.packet.PPacketDebug
|
import cc.maxmc.msm.common.network.packet.PPacketDebug
|
||||||
import cc.maxmc.msm.common.utils.debug
|
import cc.maxmc.msm.common.utils.debug
|
||||||
import com.google.common.collect.HashBiMap
|
import com.google.common.collect.HashBiMap
|
||||||
|
|
@ -11,9 +13,16 @@ object NetworkRegistry {
|
||||||
private val childBoundMap = HashBiMap.create<Int, Class<out BungeePacket>>()
|
private val childBoundMap = HashBiMap.create<Int, Class<out BungeePacket>>()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
debug("init registry")
|
|
||||||
registerPacket(PacketDirection.PARENT_BOUND, PPacketDebug::class.java)
|
registerPacket(PacketDirection.PARENT_BOUND, PPacketDebug::class.java)
|
||||||
|
registerPacket(PacketDirection.PARENT_BOUND, PPacketAPICall.PPacketCallGetPlayerServer::class.java)
|
||||||
|
registerPacket(PacketDirection.PARENT_BOUND, PPacketAPICall.PPacketCallContainPlayer::class.java)
|
||||||
|
registerPacket(PacketDirection.PARENT_BOUND, PPacketAPICall.PPacketCallInformEnd::class.java)
|
||||||
|
registerPacket(PacketDirection.PARENT_BOUND, PPacketAPICall.PPacketCallGetServer::class.java)
|
||||||
registerPacket(PacketDirection.CHILD_BOUND, CPacketDebug::class.java)
|
registerPacket(PacketDirection.CHILD_BOUND, CPacketDebug::class.java)
|
||||||
|
registerPacket(PacketDirection.CHILD_BOUND, CPacketAPICallback.CPacketCallbackGetPlayerServer::class.java)
|
||||||
|
registerPacket(PacketDirection.CHILD_BOUND, CPacketAPICallback.CPacketCallbackContainPlayer::class.java)
|
||||||
|
registerPacket(PacketDirection.CHILD_BOUND, CPacketAPICallback.CPacketCallbackInformEnd::class.java)
|
||||||
|
registerPacket(PacketDirection.CHILD_BOUND, CPacketAPICallback.CPacketCallbackGetServer::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerPacket(direction: PacketDirection, packet: Class<out BungeePacket>) {
|
private fun registerPacket(direction: PacketDirection, packet: Class<out BungeePacket>) {
|
||||||
|
|
@ -27,9 +36,7 @@ object NetworkRegistry {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getPacketID(side: PacketDirection, packet: BungeePacket): Int {
|
fun getPacketID(side: PacketDirection, packet: BungeePacket): Int {
|
||||||
debug("start get PID")
|
|
||||||
val map = if (side == PacketDirection.PARENT_BOUND) childBoundMap else parentBoundMap
|
val map = if (side == PacketDirection.PARENT_BOUND) childBoundMap else parentBoundMap
|
||||||
debug("map use $map")
|
|
||||||
return map.inverse()[packet::class.java] ?: throw IllegalStateException("Packet does not in registry.")
|
return map.inverse()[packet::class.java] ?: throw IllegalStateException("Packet does not in registry.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package cc.maxmc.msm.common.network.packet
|
||||||
|
|
||||||
|
import cc.maxmc.msm.api.misc.ServerInfo
|
||||||
|
import cc.maxmc.msm.common.network.BungeePacket
|
||||||
|
import cc.maxmc.msm.common.utils.readServerInfo
|
||||||
|
import cc.maxmc.msm.common.utils.writeServerInfo
|
||||||
|
import io.netty.buffer.ByteBuf
|
||||||
|
import net.md_5.bungee.protocol.DefinedPacket
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
sealed class CPacketAPICallback(
|
||||||
|
var uid: UUID
|
||||||
|
) : BungeePacket() {
|
||||||
|
override fun encode(buf: ByteBuf) {
|
||||||
|
DefinedPacket.writeUUID(uid, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buf: ByteBuf) {
|
||||||
|
uid = DefinedPacket.readUUID(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPacketCallbackGetServer(
|
||||||
|
var serverInfo: ServerInfo = ServerInfo(),
|
||||||
|
uid: UUID = UUID.randomUUID()
|
||||||
|
) : CPacketAPICallback(uid = uid) {
|
||||||
|
override fun encode(buf: ByteBuf) {
|
||||||
|
super.encode(buf)
|
||||||
|
buf.writeServerInfo(serverInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buf: ByteBuf) {
|
||||||
|
super.decode(buf)
|
||||||
|
serverInfo = buf.readServerInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPacketCallbackInformEnd(
|
||||||
|
uid: UUID = UUID.randomUUID()
|
||||||
|
) : CPacketAPICallback(uid = uid)
|
||||||
|
|
||||||
|
class CPacketCallbackGetPlayerServer(
|
||||||
|
var serverInfo: ServerInfo,
|
||||||
|
uid: UUID = UUID.randomUUID()
|
||||||
|
) : CPacketAPICallback(uid = uid) {
|
||||||
|
override fun encode(buf: ByteBuf) {
|
||||||
|
super.encode(buf)
|
||||||
|
buf.writeServerInfo(serverInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buf: ByteBuf) {
|
||||||
|
super.decode(buf)
|
||||||
|
serverInfo = buf.readServerInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CPacketCallbackContainPlayer(
|
||||||
|
var value: Boolean,
|
||||||
|
uid: UUID = UUID.randomUUID()
|
||||||
|
) : CPacketAPICallback(uid = uid) {
|
||||||
|
override fun encode(buf: ByteBuf) {
|
||||||
|
super.encode(buf)
|
||||||
|
buf.writeBoolean(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun decode(buf: ByteBuf) {
|
||||||
|
super.decode(buf)
|
||||||
|
value = buf.readBoolean()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,11 +4,9 @@ import cc.maxmc.msm.common.network.BungeePacket
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
|
|
||||||
data class CPacketDebug(
|
data class CPacketDebug(
|
||||||
var content: String
|
var content: String = ""
|
||||||
) : BungeePacket() {
|
) : BungeePacket() {
|
||||||
|
|
||||||
constructor() : this("")
|
|
||||||
|
|
||||||
override fun encode(buf: ByteBuf) {
|
override fun encode(buf: ByteBuf) {
|
||||||
val array = content.encodeToByteArray()
|
val array = content.encodeToByteArray()
|
||||||
buf.writeInt(array.size)
|
buf.writeInt(array.size)
|
||||||
|
|
@ -17,6 +15,8 @@ data class CPacketDebug(
|
||||||
|
|
||||||
override fun decode(buf: ByteBuf) {
|
override fun decode(buf: ByteBuf) {
|
||||||
val size = buf.readInt()
|
val size = buf.readInt()
|
||||||
content = buf.readBytes(size).array().decodeToString()
|
val encoded = ByteArray(size)
|
||||||
|
buf.readBytes(encoded)
|
||||||
|
content = encoded.decodeToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package cc.maxmc.msm.common.network.packet
|
package cc.maxmc.msm.common.network.packet
|
||||||
|
|
||||||
import cc.maxmc.msm.common.network.BungeePacket
|
import cc.maxmc.msm.common.network.BungeePacket
|
||||||
import cc.maxmc.msm.common.utils.debug
|
|
||||||
import io.netty.buffer.ByteBuf
|
import io.netty.buffer.ByteBuf
|
||||||
|
|
||||||
data class PPacketDebug(
|
data class PPacketDebug(
|
||||||
|
|
@ -9,11 +8,9 @@ data class PPacketDebug(
|
||||||
) : BungeePacket() {
|
) : BungeePacket() {
|
||||||
|
|
||||||
override fun encode(buf: ByteBuf) {
|
override fun encode(buf: ByteBuf) {
|
||||||
debug("start packet encode")
|
|
||||||
val array = content.encodeToByteArray()
|
val array = content.encodeToByteArray()
|
||||||
buf.writeInt(array.size)
|
buf.writeInt(array.size)
|
||||||
buf.writeBytes(array)
|
buf.writeBytes(array)
|
||||||
debug("end packet encode")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun decode(buf: ByteBuf) {
|
override fun decode(buf: ByteBuf) {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ fun log(msg: String) {
|
||||||
|
|
||||||
val debug = true
|
val debug = true
|
||||||
|
|
||||||
fun debug(msg: String) {
|
//fun debug(msg: String) {
|
||||||
if (debug) {
|
// if (debug) {
|
||||||
log("§fDEBUG | §7$msg")
|
// log("§fDEBUG | §7$msg")
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package cc.maxmc.msm.parent
|
package cc.maxmc.msm.parent
|
||||||
|
|
||||||
|
import cc.maxmc.msm.api.MultiServerManAPIProvider
|
||||||
|
import cc.maxmc.msm.parent.api.APIImpl
|
||||||
import cc.maxmc.msm.parent.listener.PacketListener
|
import cc.maxmc.msm.parent.listener.PacketListener
|
||||||
import cc.maxmc.msm.parent.netty.NetManager
|
import cc.maxmc.msm.parent.netty.NetManager
|
||||||
import net.md_5.bungee.api.ProxyServer
|
import net.md_5.bungee.api.ProxyServer
|
||||||
|
|
@ -9,6 +11,7 @@ class MultiServerMan : Plugin() {
|
||||||
|
|
||||||
override fun onEnable() {
|
override fun onEnable() {
|
||||||
instance = this
|
instance = this
|
||||||
|
MultiServerManAPIProvider.register(APIImpl)
|
||||||
ProxyServer.getInstance().pluginManager.registerListener(this, PacketListener)
|
ProxyServer.getInstance().pluginManager.registerListener(this, PacketListener)
|
||||||
NetManager.startServer()
|
NetManager.startServer()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cc.maxmc.msm.parent.api
|
||||||
|
|
||||||
|
import cc.maxmc.msm.api.MultiServerManAPI
|
||||||
|
import cc.maxmc.msm.api.misc.ServerInfo
|
||||||
|
import com.google.common.net.HostAndPort
|
||||||
|
|
||||||
|
object APIImpl : MultiServerManAPI {
|
||||||
|
override fun getServer(type: String, players: MutableList<String>): ServerInfo {
|
||||||
|
TODO("not implemented")
|
||||||
|
return ServerInfo(HostAndPort.fromString("127.0.0.1:23456"), 1024)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun informEnd(id: Int) {
|
||||||
|
TODO("not implemented")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPlayerServer(player: String): ServerInfo {
|
||||||
|
TODO("not implemented")
|
||||||
|
return ServerInfo(HostAndPort.fromString("127.0.0.1:34567"), 1025)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun containPlayer(player: String): Boolean {
|
||||||
|
TODO("not implemented")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,22 +2,84 @@ package cc.maxmc.msm.parent.database
|
||||||
|
|
||||||
import cc.maxmc.msm.parent.settings.Settings
|
import cc.maxmc.msm.parent.settings.Settings
|
||||||
import com.zaxxer.hikari.HikariConfig
|
import com.zaxxer.hikari.HikariConfig
|
||||||
|
import com.zaxxer.hikari.pool.HikariPool
|
||||||
|
import java.sql.Timestamp
|
||||||
|
|
||||||
class SQLDatabase {
|
class SQLDatabase {
|
||||||
val config = HikariConfig()
|
private val config = HikariConfig()
|
||||||
|
private lateinit var pool: HikariPool
|
||||||
fun initDatabase() {
|
fun initDatabase() {
|
||||||
val db = Settings.Database
|
val db = Settings.Database
|
||||||
config.jdbcUrl = "jdbc:mysql://${db.address}:${db.port}"
|
config.jdbcUrl = "jdbc:mysql://${db.address}:${db.port}"
|
||||||
config.username = db.username
|
config.username = db.username
|
||||||
config.password = db.password
|
config.password = db.password
|
||||||
config.schema = db.database
|
config.schema = db.database
|
||||||
|
pool = HikariPool(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getMatch(id: Int) {
|
fun createTable() {
|
||||||
|
pool.connection.use {
|
||||||
|
it.createStatement().use { statement ->
|
||||||
|
statement.execute(
|
||||||
|
"""
|
||||||
|
CREATE TABLE `match`
|
||||||
|
(
|
||||||
|
`id` int auto_increment,
|
||||||
|
`start` datetime not null,
|
||||||
|
`end` datetime null,
|
||||||
|
`players` text not null ,
|
||||||
|
PRIMARY KEY (`id`)
|
||||||
|
)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun recordMatch() {
|
fun getPlayerMatch(player: String): Int {
|
||||||
|
pool.connection.use {
|
||||||
|
it.prepareStatement("select `id` from `match` where find_in_set(?, players) AND end IS NULL")
|
||||||
|
.use { prepared ->
|
||||||
|
prepared.setString(0, player)
|
||||||
|
val rs = prepared.executeQuery()
|
||||||
|
if (!rs.next()) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
return rs.getInt(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun recordMatch(type: String, players: List<String>, start: Long = System.currentTimeMillis()) =
|
||||||
|
pool.connection.use {
|
||||||
|
val prepared = it.prepareStatement(
|
||||||
|
"""
|
||||||
|
insert into `match` (type, start, end, players)
|
||||||
|
values (?, ?, ?, ?);
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
prepared.apply {
|
||||||
|
setString(1, type)
|
||||||
|
setTimestamp(2, Timestamp(start))
|
||||||
|
setTimestamp(3, null)
|
||||||
|
setString(4, players.joinToString(","))
|
||||||
|
}
|
||||||
|
prepared.execute()
|
||||||
|
prepared.close()
|
||||||
|
return@use it.createStatement().use { statement ->
|
||||||
|
val result = statement.executeQuery("select last_insert_id()")
|
||||||
|
result.next()
|
||||||
|
result.getInt(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun endMatch(id: Int, end: Long = System.currentTimeMillis()) = pool.connection.use {
|
||||||
|
val prepare = it.prepareStatement("update `match` set end = ? where id = ?")
|
||||||
|
prepare.apply {
|
||||||
|
setTimestamp(1, Timestamp(end))
|
||||||
|
setInt(2, id)
|
||||||
|
}
|
||||||
|
prepare.execute()
|
||||||
|
prepare.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,44 @@
|
||||||
package cc.maxmc.msm.parent.listener
|
package cc.maxmc.msm.parent.listener
|
||||||
|
|
||||||
|
import cc.maxmc.msm.api.MultiServerManAPIProvider
|
||||||
import cc.maxmc.msm.common.event.PacketReceiveEvent
|
import cc.maxmc.msm.common.event.PacketReceiveEvent
|
||||||
|
import cc.maxmc.msm.common.network.packet.CPacketAPICallback
|
||||||
import cc.maxmc.msm.common.network.packet.CPacketDebug
|
import cc.maxmc.msm.common.network.packet.CPacketDebug
|
||||||
|
import cc.maxmc.msm.common.network.packet.PPacketAPICall
|
||||||
import cc.maxmc.msm.common.network.packet.PPacketDebug
|
import cc.maxmc.msm.common.network.packet.PPacketDebug
|
||||||
|
import cc.maxmc.msm.common.utils.debug
|
||||||
import cc.maxmc.msm.common.utils.log
|
import cc.maxmc.msm.common.utils.log
|
||||||
import net.md_5.bungee.api.plugin.Listener
|
import net.md_5.bungee.api.plugin.Listener
|
||||||
import net.md_5.bungee.event.EventHandler
|
import net.md_5.bungee.event.EventHandler
|
||||||
|
|
||||||
object PacketListener : Listener {
|
object PacketListener : Listener {
|
||||||
|
val api = MultiServerManAPIProvider.getAPI()
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun onAPICall(evt: PacketReceiveEvent) {
|
||||||
|
val packet = evt.packet
|
||||||
|
if (packet !is PPacketAPICall) return
|
||||||
|
val callback = when (packet) {
|
||||||
|
is PPacketAPICall.PPacketCallContainPlayer -> {
|
||||||
|
CPacketAPICallback.CPacketCallbackContainPlayer(api.containPlayer(packet.player), packet.uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
is PPacketAPICall.PPacketCallGetPlayerServer -> {
|
||||||
|
CPacketAPICallback.CPacketCallbackGetPlayerServer(api.getPlayerServer(packet.player), packet.uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
is PPacketAPICall.PPacketCallGetServer -> {
|
||||||
|
CPacketAPICallback.CPacketCallbackGetServer(api.getServer(packet.type, packet.players), packet.uid)
|
||||||
|
}
|
||||||
|
|
||||||
|
is PPacketAPICall.PPacketCallInformEnd -> {
|
||||||
|
api.informEnd(packet.matchID)
|
||||||
|
CPacketAPICallback.CPacketCallbackInformEnd(packet.uid)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
evt.channel.writeAndFlush(callback)
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
fun onPacket(evt: PacketReceiveEvent) {
|
fun onPacket(evt: PacketReceiveEvent) {
|
||||||
val packet = evt.packet
|
val packet = evt.packet
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,6 @@ object ChildManager {
|
||||||
val children = ArrayList<ChildBungee>()
|
val children = ArrayList<ChildBungee>()
|
||||||
|
|
||||||
fun registerChild(child: ChildBungee) {
|
fun registerChild(child: ChildBungee) {
|
||||||
|
children.add(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
package cc.maxmc.msm.parent.misc
|
package cc.maxmc.msm.parent.misc
|
||||||
|
|
||||||
|
import cc.maxmc.msm.common.network.BungeePacket
|
||||||
import io.netty.channel.Channel
|
import io.netty.channel.Channel
|
||||||
|
|
||||||
data class ChildBungee(val channel: Channel)
|
class ChildBungee(val channel: Channel, var ports: List<Int>, var usedPorts: List<Int> = ArrayList()) {
|
||||||
|
fun sendPacket(packet: BungeePacket) {
|
||||||
|
channel.writeAndFlush(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ object NetManager {
|
||||||
.childHandler(pipelineInit(NetworkRegistry.PacketDirection.PARENT_BOUND))
|
.childHandler(pipelineInit(NetworkRegistry.PacketDirection.PARENT_BOUND))
|
||||||
.bind(Settings.serverPort)
|
.bind(Settings.serverPort)
|
||||||
.addListener(ChannelFutureListener {
|
.addListener(ChannelFutureListener {
|
||||||
log("§a| §7集群主服务端启动成功. ${it.channel().localAddress()}")
|
val result = it.cause() ?: return@ChannelFutureListener log(
|
||||||
|
"§a| §7集群主服务端启动成功. ${
|
||||||
|
it.channel().localAddress()
|
||||||
|
}"
|
||||||
|
)
|
||||||
|
result.printStackTrace()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue