feat: add player Names Throughout the Game UI
This commit is contained in:
+3
-2
@@ -268,11 +268,12 @@ bool http_api_handle(http_api_t *api, const http_api_request_t *request, http_ap
|
||||
uint8_t spectators = 0;
|
||||
for (uint8_t index = kPlayerCapacity; index < kSessionCapacity; ++index) spectators += sessions->entries[index].occupied;
|
||||
response_write(response, 200U, "{\"ok\":true,\"phase\":\"%s\",\"gameId\":%" PRIu32 ",\"version\":%" PRIu32
|
||||
",\"player1Available\":%s,\"player2Available\":%s,\"spectatorsAvailable\":%u}",
|
||||
",\"player1Available\":%s,\"player2Available\":%s,\"player1Name\":\"%s\",\"player2Name\":\"%s\",\"spectatorsAvailable\":%u}",
|
||||
phase_text(lifecycle->game.state.phase), lifecycle->game.state.game_id, version,
|
||||
sessions->entries[0].occupied ? "false" : "true", sessions->entries[1].occupied ? "false" : "true",
|
||||
sessions->entries[0].occupied ? sessions->entries[0].name : "", sessions->entries[1].occupied ? sessions->entries[1].name : "",
|
||||
(unsigned int)(kSpectatorCapacity - spectators));
|
||||
return response->body_length <= 192U;
|
||||
return response->body_length <= 384U;
|
||||
}
|
||||
if (request->route == HTTP_API_ROUTE_HEALTH && request->method == HTTP_API_GET) {
|
||||
response_write(response, 200U, "{\"ok\":true,\"uptimeMs\":%" PRIu32 ",\"wifiState\":\"%s\",\"freeHeapBytes\":%" PRIu32
|
||||
|
||||
@@ -14,11 +14,16 @@ static bool valid_utf8_scalar(const unsigned char *text, size_t remaining, size_
|
||||
static bool sanitize_name(const char *name, char output[kDisplayNameBytes + 1]) {
|
||||
if (name == NULL) return false;
|
||||
size_t input = 0;
|
||||
while (name[input] == ' ') ++input;
|
||||
const size_t start = input;
|
||||
size_t end = start;
|
||||
while (name[end] != '\0') ++end;
|
||||
while (end > start && name[end - 1U] == ' ') --end;
|
||||
size_t written = 0;
|
||||
uint8_t scalars = 0;
|
||||
while (name[input] != '\0') {
|
||||
while (input < end) {
|
||||
size_t bytes = 0;
|
||||
if (!valid_utf8_scalar((const unsigned char *)&name[input], strlen(&name[input]), &bytes)) return false;
|
||||
if (!valid_utf8_scalar((const unsigned char *)&name[input], end - input, &bytes) || name[input] == '"' || name[input] == '\\') return false;
|
||||
if (written + bytes > kDisplayNameBytes || ++scalars > 20U) return false;
|
||||
memcpy(&output[written], &name[input], bytes);
|
||||
input += bytes;
|
||||
|
||||
+12
-4
@@ -16,6 +16,13 @@ static bool append_text(state_writer_t *writer, const char *text) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool append_player_names(state_writer_t *writer, const session_manager_t *sessions) {
|
||||
const char *first = sessions != NULL && sessions->entries[0].occupied ? sessions->entries[0].name : "";
|
||||
const char *second = sessions != NULL && sessions->entries[1].occupied ? sessions->entries[1].name : "";
|
||||
return append_text(writer, ",\"players\":[\"") && append_text(writer, first) &&
|
||||
append_text(writer, "\",\"") && append_text(writer, second) && append_text(writer, "\"]");
|
||||
}
|
||||
|
||||
static bool append_u32(state_writer_t *writer, uint32_t value) {
|
||||
char digits[10];
|
||||
uint8_t count = 0;
|
||||
@@ -75,7 +82,7 @@ static bool append_statistics(state_writer_t *writer, const match_statistics_t *
|
||||
append_character(writer, ',') && append_u32(writer, statistics->ships_sunk) && append_character(writer, ']');
|
||||
}
|
||||
|
||||
static bool write_state(const game_state_t *state, role_t viewer, const cumulative_statistics_t *cumulative,
|
||||
static bool write_state(const game_state_t *state, const session_manager_t *sessions, role_t viewer, const cumulative_statistics_t *cumulative,
|
||||
char *output, size_t output_size, size_t *written) {
|
||||
if (written != NULL) *written = 0;
|
||||
if (state == NULL || output == NULL || output_size == 0U || phase_name(state->phase) == NULL ||
|
||||
@@ -91,7 +98,8 @@ static bool write_state(const game_state_t *state, role_t viewer, const cumulati
|
||||
!append_text(&writer, "\",\"mode\":\"") || !append_text(&writer, mode_name(state->mode)) ||
|
||||
!append_text(&writer, "\",\"viewer\":\"") || !append_text(&writer, role_name(viewer)) ||
|
||||
!append_text(&writer, "\",\"turn\":\"") || !append_text(&writer, role_name((role_t)state->current_player)) ||
|
||||
!append_text(&writer, "\",\"boards\":[\"") || !append_board(&writer, &state->boards[0], reveal[0]) ||
|
||||
!append_text(&writer, "\"") || !append_player_names(&writer, sessions) ||
|
||||
!append_text(&writer, ",\"boards\":[\"") || !append_board(&writer, &state->boards[0], reveal[0]) ||
|
||||
!append_text(&writer, "\",\"") || !append_board(&writer, &state->boards[1], reveal[1]) ||
|
||||
!append_text(&writer, "\"],\"wins\":[") || !append_u32(&writer, wins_0) ||
|
||||
!append_character(&writer, ',') || !append_u32(&writer, wins_1) ||
|
||||
@@ -108,11 +116,11 @@ static bool write_state(const game_state_t *state, role_t viewer, const cumulati
|
||||
}
|
||||
|
||||
bool state_presenter_write(const game_state_t *state, role_t viewer, char *output, size_t output_size, size_t *written) {
|
||||
return write_state(state, viewer, NULL, output, output_size, written);
|
||||
return write_state(state, NULL, viewer, NULL, output, output_size, written);
|
||||
}
|
||||
|
||||
bool state_presenter_write_lifecycle(const game_lifecycle_t *lifecycle, role_t viewer,
|
||||
char *output, size_t output_size, size_t *written) {
|
||||
return lifecycle != NULL && write_state(&lifecycle->game.state, viewer, lifecycle->cumulative,
|
||||
return lifecycle != NULL && write_state(&lifecycle->game.state, &lifecycle->sessions, viewer, lifecycle->cumulative,
|
||||
output, output_size, written);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user