@@ -10,6 +10,7 @@ import net.minecraft.locale.Language
1010import net.minecraft.network.chat.Component
1111import net.minecraft.server.MinecraftServer
1212import org.apache.logging.log4j.LogManager
13+ import kotlin.time.Duration.Companion.seconds
1314
1415class ExchangeServer (
1516 private val minecraftServer : MinecraftServer ,
@@ -21,18 +22,28 @@ class ExchangeServer(
2122 private var launched = false
2223
2324 private suspend fun serverRoutine () {
24- val host = ChatExchangeConfig .host.get()
25- val port = ChatExchangeConfig .port.get()
26-
27- logger.info(" Starting exchange server on $host :$port ..." )
28- val serverSocket = aSocket(manager).tcp().bind(host, port)
29- serverSocket.use {
30- while (isActive) {
31- val socket = serverSocket.accept()
32- logger.info(" New connection from ${socket.remoteAddress} " )
33- scope.launch {
34- handleRoutine(socket)
25+ while (isActive) {
26+ kotlin.runCatching {
27+ val host = ChatExchangeConfig .host.get()
28+ val port = ChatExchangeConfig .port.get()
29+
30+ logger.info(" Starting exchange server on $host :$port ..." )
31+ val serverSocket = aSocket(manager).tcp().bind(host, port)
32+ serverSocket.use {
33+ while (isActive) {
34+ val socket = serverSocket.accept()
35+ logger.info(" New connection from ${socket.remoteAddress} " )
36+ scope.launch {
37+ handleRoutine(socket)
38+ }
39+ }
3540 }
41+ }.onFailure {
42+ if (! isActive) {
43+ return
44+ }
45+ logger.error(" Server crashed! Will try to restart in 30 seconds." , it)
46+ delay(30 .seconds)
3647 }
3748 }
3849 }
@@ -44,35 +55,37 @@ class ExchangeServer(
4455
4556 private suspend fun handleRoutine (socket : Socket ) {
4657 socket.use {
47- val sendChannel = socket.openWriteChannel(autoFlush = true )
4858 kotlin.runCatching {
49- val receiveChannel = socket.openReadChannel()
50-
51- if (token.isNotBlank()) {
52- sendChannel.writeExchangeEvent(AuthenticateEvent (required = true ))
53- val actualToken = (receiveChannel.readExchangeEvent() as ? AuthenticateEvent )?.token
54- if (token != actualToken) {
55- sendChannel.writeExchangeEvent(AuthenticateEvent (success = false ))
56- return @runCatching
59+ val sendChannel = socket.openWriteChannel(autoFlush = true )
60+ kotlin.runCatching inner@{
61+ val receiveChannel = socket.openReadChannel()
62+
63+ if (token.isNotBlank()) {
64+ sendChannel.writeExchangeEvent(AuthenticateEvent (required = true ))
65+ val actualToken = (receiveChannel.readExchangeEvent() as ? AuthenticateEvent )?.token
66+ if (token != actualToken) {
67+ sendChannel.writeExchangeEvent(AuthenticateEvent (success = false ))
68+ return @inner
69+ }
70+ sendChannel.writeExchangeEvent(AuthenticateEvent (success = true ))
71+ } else {
72+ sendChannel.writeExchangeEvent(AuthenticateEvent (required = false ))
5773 }
58- sendChannel.writeExchangeEvent(AuthenticateEvent (success = true ))
59- } else {
60- sendChannel.writeExchangeEvent(AuthenticateEvent (required = false ))
61- }
6274
63- channelMutex.withLock {
64- sendChannels + = sendChannel
65- }
75+ channelMutex.withLock {
76+ sendChannels + = sendChannel
77+ }
6678
67- receiveRoutine(receiveChannel)
79+ receiveRoutine(receiveChannel)
80+ }
81+ withContext(NonCancellable ) {
82+ channelMutex.withLock {
83+ sendChannels - = sendChannel
84+ }
85+ }
6886 }.onFailure {
6987 logger.info(" Exception during handling connection." , it)
7088 }
71- withContext(NonCancellable ) {
72- channelMutex.withLock {
73- sendChannels - = sendChannel
74- }
75- }
7689 }
7790 logger.info(" A connection closed." )
7891 }
0 commit comments