Skip to content

Commit

Permalink
fix(server): appropriately handle empty slots at game start
Browse files Browse the repository at this point in the history
  • Loading branch information
xeruf committed Mar 16, 2022
1 parent 8952424 commit f74572a
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 5 deletions.
5 changes: 3 additions & 2 deletions sdk/src/main/server-api/sc/framework/plugins/Player.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField
import org.slf4j.LoggerFactory
import sc.api.plugins.ITeam
import sc.api.plugins.host.IPlayerListener
import sc.networking.clients.XStreamClient.DisconnectCause
import sc.protocol.room.MoveRequest
import sc.protocol.room.RoomMessage
import sc.util.PlayerConverter
Expand Down Expand Up @@ -37,9 +38,9 @@ class Player @JvmOverloads constructor(
var canTimeout: Boolean = false

@XStreamOmitField
var left = false
var left: DisconnectCause? = null

fun hasLeft() = left
fun hasLeft() = left != null

@XStreamOmitField
var softTimeout = false
Expand Down
2 changes: 1 addition & 1 deletion sdk/src/main/server-api/sc/protocol/RemovedFromGame.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ import com.thoughtworks.xstream.annotations.XStreamAsAttribute
data class RemovedFromGame(
@XStreamAsAttribute
val roomId: String
): ProtocolPacket
): ResponsePacket
10 changes: 8 additions & 2 deletions server/src/main/java/sc/server/gaming/GameRoom.java
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,10 @@ public synchronized void step(boolean forced) {
if (getStatus() == GameStatus.CREATED) {
if (forced) {
logger.warn("Forcing game start for {}", game);
start();
if(getClients().size() < 2)
cancel();
else
start();
} else {
logger.info("Game isn't active yet, step was not forced.");
}
Expand Down Expand Up @@ -406,7 +409,10 @@ protected void setStatus(GameStatus status) {
/** Remove a player and stop the game. */
public void removePlayer(Player player, XStreamClient.DisconnectCause cause) {
logger.info("Removing {} from {}", player, this);
player.setLeft(true);
// Mark all non-joined players as left to trigger a draw when noone joined
// Might be superfluous through the check in "step", but keeping for safety
playerSlots.forEach(slot -> slot.getPlayer().setLeft(slot.isEmpty() ? cause : null));
player.setLeft(cause);
if (!isOver())
cancel();
}
Expand Down
13 changes: 13 additions & 0 deletions server/src/test/java/sc/server/network/LobbyGameTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import io.kotest.matchers.collections.*
import io.kotest.matchers.nulls.*
import io.kotest.matchers.string.*
import sc.api.plugins.Team
import sc.protocol.RemovedFromGame
import sc.protocol.ResponsePacket
import sc.protocol.requests.JoinPreparedRoomRequest
import sc.protocol.requests.PrepareGameRequest
Expand Down Expand Up @@ -95,6 +96,18 @@ class LobbyGameTest: WordSpec({
room.clients.shouldBeEmpty()
room.isPauseRequested shouldBe true
}

"return GameResult on step" {
val roomListener = observeRoom(room.id)
admin.control(room.id).step(true)
val result = roomListener.waitForMessage(GameResult::class)
withClue("No Winner") {
result.winner shouldBe null
}
adminListener.waitForMessage(RemovedFromGame::class)
roomListener.clearMessages() shouldBe 0
admin.closed shouldBe false
}

val reservations = prepared.reservations
players[0].joinGameWithReservation(reservations[0])
Expand Down

0 comments on commit f74572a

Please sign in to comment.