Skip to content

Commit

Permalink
Graceful shutdown of network sockets
Browse files Browse the repository at this point in the history
  • Loading branch information
Martomate committed Aug 1, 2024
1 parent 6e215af commit 5005d05
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 17 deletions.
46 changes: 32 additions & 14 deletions client/src/main/scala/hexacraft/client/GameClient.scala
Original file line number Diff line number Diff line change
Expand Up @@ -41,22 +41,13 @@ object GameClient {
): Result[(GameClient, Channel.Receiver[GameClient.Event]), String] = {
val socket = GameClientSocket(serverIp, serverPort)

val loginResponse = socket.sendPacketAndWait(NetworkPacket.Login(playerId, "Some name")).asMap.get
val loginSuccessful = loginResponse.getBoolean("success", false)
if !loginSuccessful then {
val errorMessage = loginResponse.getString("error", "")
return Result.Err(s"failed to login: $errorMessage")
val (worldInfo, player) = fetchWorldInfo(socket, playerId) match {
case Result.Ok(value) => value
case Result.Err(message) =>
socket.close()
return Result.Err(s"failed to connect to server: $message")
}

val worldInfo = WorldInfo.fromNBT(
socket.sendPacketAndWait(NetworkPacket.GetWorldInfo).asInstanceOf[Nbt.MapTag],
null,
WorldSettings.none
)

val playerNbt = socket.sendPacketAndWait(NetworkPacket.GetPlayerState)
val player = Player.fromNBT(playerId, playerNbt.asInstanceOf[Nbt.MapTag])

val blockSpecs = BlockSpecs.default
val blockTextureMapping = loadBlockTextures(blockSpecs, blockLoader)
val blockTextureIndices: Map[String, IndexedSeq[Int]] =
Expand Down Expand Up @@ -133,6 +124,29 @@ object GameClient {
Result.Ok((client, rx))
}

private def fetchWorldInfo(socket: GameClientSocket, playerId: UUID): Result[(WorldInfo, Player), String] = try {
val loginResponse = socket.sendPacketAndWait(NetworkPacket.Login(playerId, "Some name")).asMap.get
val loginSuccessful = loginResponse.getBoolean("success", false)
if !loginSuccessful then {
val errorMessage = loginResponse.getString("error", "")
return Result.Err(s"failed to login: $errorMessage")
}

val worldInfo = WorldInfo.fromNBT(
socket.sendPacketAndWait(NetworkPacket.GetWorldInfo).asMap.get,
null,
WorldSettings.none
)

val playerNbt = socket.sendPacketAndWait(NetworkPacket.GetPlayerState)
val player = Player.fromNBT(playerId, playerNbt.asMap.get)

Result.Ok((worldInfo, player))
} catch {
case e: Exception =>
Result.Err(e.getMessage)
}

private def calculateTextureColor(texture: PixelArray): Vector3f = {
var r = 0L
var g = 0L
Expand Down Expand Up @@ -918,5 +932,9 @@ class GameClientSocket(serverIp: String, serverPort: Int) {
context.synchronized {
context.close()
}

if monitoringThread != null then {
monitoringThread.interrupt()
}
}
}
9 changes: 6 additions & 3 deletions main/src/main/scala/hexacraft/main/GameScene.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import hexacraft.main.GameScene.Event.{CursorCaptured, CursorReleased, GameQuit}
import hexacraft.server.GameServer
import hexacraft.util.{Channel, Result}
import hexacraft.world.WorldProvider
import hexacraft.world.block.BlockSpec

import java.util.UUID

Expand Down Expand Up @@ -50,8 +49,12 @@ object GameScene {
c.initialWindowSize,
c.audioSystem
) match {
case Result.Ok(res) => res
case Result.Err(message) => return Result.Err(s"failed to start game: $message")
case Result.Ok(res) => res
case Result.Err(message) =>
if server.isDefined then {
server.get.unload()
}
return Result.Err(s"failed to start game: $message")
}

clientEvents.onEvent {
Expand Down
2 changes: 2 additions & 0 deletions server/src/test/scala/hexacraft/world/ServerWorldTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ class ServerWorldTest extends FunSuite {
Thread.sleep(20)
world.tick(Seq(camera), Seq(), Seq())

assert(world.getChunk(ChunkRelWorld(0, 0, 0)).isDefined)

val entity = Entity(
UUID.randomUUID(),
"scorpion",
Expand Down

0 comments on commit 5005d05

Please sign in to comment.