feat(session): add explicit leave and immediate slot release
This commit is contained in:
@@ -948,6 +948,40 @@ static void handle_message(maze32_gateway_t* gateway, maze32_gateway_connection_
|
||||
"Сначала выберите роль или восстановите сессию");
|
||||
return;
|
||||
}
|
||||
if (message->type == MAZE32_MESSAGE_LEAVE) {
|
||||
maze32_role_t leaving_role = session->role;
|
||||
int cancel_match = leaving_role == MAZE32_ROLE_PLAYER &&
|
||||
gateway->lobby.phase != MAZE32_LOBBY_WAITING &&
|
||||
gateway->game.phase != MAZE32_GAME_PHASE_FINISHED;
|
||||
char acknowledgement[192] = "";
|
||||
size_t length = 0U;
|
||||
char prefix[96];
|
||||
int written = snprintf(prefix, sizeof(prefix),
|
||||
"{\"v\":1,\"type\":\"ack\",\"seq\":%" PRIu32 ",\"requestId\":",
|
||||
next_server_sequence(gateway));
|
||||
if (written >= 0 && (size_t)written < sizeof(prefix) &&
|
||||
append_text(acknowledgement, sizeof(acknowledgement), &length, prefix) &&
|
||||
append_json_string(acknowledgement, sizeof(acknowledgement), &length,
|
||||
message->request_id) &&
|
||||
append_text(acknowledgement, sizeof(acknowledgement), &length,
|
||||
",\"payload\":{\"command\":\"leave\"}}")) {
|
||||
enqueue(gateway, socket_fd, acknowledgement);
|
||||
}
|
||||
if (cancel_match) {
|
||||
esp_timer_stop(gateway->countdown_timer);
|
||||
esp_timer_stop(gateway->reconnect_timer);
|
||||
esp_timer_stop(gateway->finish_timer);
|
||||
initialize_game(gateway);
|
||||
maze32_lobby_reset_match(&gateway->lobby);
|
||||
}
|
||||
maze32_lobby_leave(&gateway->lobby, socket_fd, NULL, NULL);
|
||||
if (cancel_match) {
|
||||
broadcast_match_event(gateway, "reset", "{}");
|
||||
}
|
||||
broadcast_snapshot(gateway);
|
||||
drain_queue(gateway);
|
||||
return;
|
||||
}
|
||||
if (message->type == MAZE32_MESSAGE_START) {
|
||||
if (session->role == MAZE32_ROLE_OBSERVER) {
|
||||
ESP_LOGW(TAG, "Observer mutation rejected: fd=%d, type=start", socket_fd);
|
||||
@@ -977,18 +1011,29 @@ static void handle_message(maze32_gateway_t* gateway, maze32_gateway_connection_
|
||||
return;
|
||||
}
|
||||
if (message->type == MAZE32_MESSAGE_HEARTBEAT) {
|
||||
int64_t heartbeat_started_us = esp_timer_get_time();
|
||||
char response[MAZE32_GATEWAY_OUTGOING_LIMIT] = "";
|
||||
size_t length = 0U;
|
||||
char prefix[128];
|
||||
char handling_text[32];
|
||||
int written = snprintf(prefix, sizeof(prefix), "{\"v\":1,\"type\":\"ack\",\"seq\":%" PRIu32,
|
||||
next_server_sequence(gateway));
|
||||
if (written >= 0 && (size_t)written < sizeof(prefix) &&
|
||||
uint64_t handling_ms = (uint64_t)(esp_timer_get_time() - heartbeat_started_us) / 1000U;
|
||||
if (handling_ms > 1000U) {
|
||||
handling_ms = 1000U;
|
||||
}
|
||||
int handling_written =
|
||||
snprintf(handling_text, sizeof(handling_text), "%" PRIu64, handling_ms);
|
||||
if (written >= 0 && (size_t)written < sizeof(prefix) && handling_written >= 0 &&
|
||||
(size_t)handling_written < sizeof(handling_text) &&
|
||||
append_text(response, sizeof(response), &length, prefix) &&
|
||||
append_text(response, sizeof(response), &length, ",\"requestId\":") &&
|
||||
append_json_string(response, sizeof(response), &length, message->request_id) &&
|
||||
append_text(response, sizeof(response), &length,
|
||||
",\"payload\":{\"command\":\"heartbeat\"}}")) {
|
||||
enqueue(gateway, socket_fd, response);
|
||||
",\"payload\":{\"command\":\"heartbeat\",\"handlingMs\":") &&
|
||||
append_text(response, sizeof(response), &length, handling_text) &&
|
||||
append_text(response, sizeof(response), &length, "}}")) {
|
||||
enqueue_with_policy(gateway, socket_fd, response, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user