Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions client/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@
- Focused text inputs own their key-down, key-up, text-input, and text-editing
events. Do not let gameplay bindings observe an event already consumed by a
focused widget.
- Region-map exploration uses a hashed cache of at most 10,000 server-received
map bitfields, scoped to the pinned connection certificate and authenticated
account. Retain initial dimensions and OR incoming snapshots/patches. Request
only region-definition paths, deduplicated and paced with socket backpressure.
Bitmap allocations total at most 1 MiB; reject excess new records without
changing the cache. Replay uses one shared 65,536-unit map/byte/set-bit budget
per frame, resumes across frames, and coalesces packets by cache revision.
RESET selects the account once per connection; duplicate active RESETs are
idempotent and account switches require disconnect. Disconnect hides cached
bits and flushes optional private disk storage. Never import character `.tiles` files or
persist client-renderer visibility in the account cache.
- Live movement diagnostics use normal authenticated connections and movement
commands in an isolated wrapper scenario. Their closed route owns gameplay
input, accepts only complete server map publications, and fails on divergence
Expand Down
31 changes: 29 additions & 2 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,8 @@ endif ()
file(STRINGS
"${atrinik_protocol_SOURCE_DIR}/generated/c/include/atrinik/protocol/game_commands.h"
ATRINIK_PROTOCOL_VERSION_LINE REGEX "^#define ATRINIK_PROTOCOL_VERSION [0-9]+U$")
if (NOT ATRINIK_PROTOCOL_VERSION_LINE MATCHES " 1081U$")
message(FATAL_ERROR "Client requires classic game protocol v1081")
if (NOT ATRINIK_PROTOCOL_VERSION_LINE MATCHES " 1082U$")
message(FATAL_ERROR "Client requires classic game protocol v1082")
endif ()
if (NOT TARGET Atrinik::Core)
set(LIBATRINIK_PACKAGE_LAYOUT ON CACHE BOOL "" FORCE)
Expand Down Expand Up @@ -758,6 +758,24 @@ if (BUILD_TESTING)
target_link_libraries(client-command-queue-tests PRIVATE Atrinik::Core SDL3::SDL3)
add_test(NAME client-command-queue COMMAND client-command-queue-tests)

if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
add_executable(client-socket-output-tests
src/tests/socket_output.c
src/client/client_command_queue.c)
atrinik_configure_target(client-socket-output-tests)
target_compile_definitions(client-socket-output-tests PRIVATE SDL_DISABLE_OLD_NAMES)
target_include_directories(client-socket-output-tests BEFORE PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/src/include
${CMAKE_CURRENT_SOURCE_DIR}/src/include
${CMAKE_CURRENT_SOURCE_DIR}/src/gui/toolkit/include
${CMAKE_CURRENT_SOURCE_DIR}/src)
target_compile_options(client-socket-output-tests PRIVATE
-ffunction-sections -fdata-sections)
target_link_options(client-socket-output-tests PRIVATE -Wl,--gc-sections)
target_link_libraries(client-socket-output-tests PRIVATE Atrinik::Core SDL3::SDL3)
add_test(NAME client-socket-output COMMAND client-socket-output-tests)
endif ()

add_executable(client-keybind-input-tests
src/tests/keybind_input.c
src/client/keybind_event.c
Expand Down Expand Up @@ -790,6 +808,14 @@ if (BUILD_TESTING)
target_link_libraries(client-move-stream-tests PRIVATE Atrinik::Core SDL3::SDL3)
add_test(NAME client-move-stream COMMAND client-move-stream-tests)

add_executable(client-region-exploration-tests
src/tests/region_exploration.c src/client/region_exploration.c)
atrinik_configure_target(client-region-exploration-tests)
target_include_directories(client-region-exploration-tests PRIVATE src/include)
target_link_libraries(client-region-exploration-tests PRIVATE Atrinik::Core OpenSSL::Crypto)
add_test(NAME client-region-exploration COMMAND client-region-exploration-tests
"${CMAKE_CURRENT_BINARY_DIR}/region-exploration-cache-test")

add_executable(client-live-movement-route-tests
src/tests/live_movement_route.c src/client/live_movement_route.c)
atrinik_configure_target(client-live-movement-route-tests)
Expand Down Expand Up @@ -1188,6 +1214,7 @@ if (BUILD_TESTING)
set_tests_properties(client-widget-priority-integration PROPERTIES
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")

add_test(NAME client-region-exploration-integration COMMAND atrinik --region-exploration-test)
add_test(NAME client-map-state-integration COMMAND atrinik --map-state-test)

endif ()
Expand Down
1 change: 1 addition & 0 deletions client/src/client/command_handlers.def
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ ATRINIK_CLIENT_COMMAND_HANDLER(INTERFACE, socket_command_interface)
ATRINIK_CLIENT_COMMAND_HANDLER(NOTIFICATION, socket_command_notification)
ATRINIK_CLIENT_COMMAND_HANDLER(KEEPALIVE, socket_command_keepalive)
ATRINIK_CLIENT_COMMAND_HANDLER(PLAYER_STATUS, socket_command_player_status)
ATRINIK_CLIENT_COMMAND_HANDLER(REGION_EXPLORATION, socket_command_region_exploration)
ATRINIK_CLIENT_COMMAND_HANDLER(ACCESS_RESULT, socket_command_access_result)
ATRINIK_CLIENT_COMMAND_HANDLER(ACCESS_ADMIN_RESULT, socket_command_access_admin_result)
ATRINIK_CLIENT_COMMAND_HANDLER(ACCESS_POLICY, socket_command_access_policy)
16 changes: 16 additions & 0 deletions client/src/client/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include <player_status.h>
#include <popup.h>
#include <region_map.h>
#include <region_exploration.h>
#include <rich_presence.h>
#include <server_files.h>
#include <settings.h>
Expand Down Expand Up @@ -1967,3 +1968,18 @@ void socket_command_control(uint8_t *data, size_t len, size_t pos) {
SDL_RaiseWindow(ScreenWindow);
}
}

void socket_command_region_exploration(uint8_t *data, size_t len, size_t pos) {
packet_reader_t reader;
packet_reader_init_at(&reader, data, len, pos);
bool changed;
if (pos > len || !region_exploration_receive(data + pos, len - pos, &changed)) {
packet_reader_set_error(&reader, PACKET_ERROR_INVALID_ENCODING);
return;
}
if (changed) {
region_map_exploration_refresh_map(data[pos] == 0 ? NULL : (const char *)data + pos + 1,
data[pos] == 0);
}
packet_reader_skip(&reader, len - pos);
}
4 changes: 0 additions & 4 deletions client/src/client/gpu_player_view.c
Original file line number Diff line number Diff line change
Expand Up @@ -1942,7 +1942,6 @@ static bool gpu_player_view_ui_region_map_prepare(void) {
region->def->num_maps = 1;
region->def->maps = xcalloc(1, sizeof(*region->def->maps));
region->def->maps[0].path = xstrdup("/gpu-ui-closure");
region->fow->path = xstrdup("gpu-ui-closure-in-memory.fow");
region->fow->bitmap = xcalloc(1, RM_MAP_FOW_BITMAP_SIZE(region));
snprintf(VS(MapData.map_path), "%s", region->def->maps[0].path);
snprintf(VS(MapData.region_name), "%s", "gpu-ui-closure");
Expand Down Expand Up @@ -2163,7 +2162,6 @@ static bool gpu_player_view_ui_closure_run(widgetdata *map_widget,
popup_destroy_all();
tooltip_dismiss();
notification_destroy();
region_map_test_fow_persistence_set(false);
metaserver_clear_data();
selected_server = metaserver_add("fixture.invalid",
13327,
Expand Down Expand Up @@ -4178,7 +4176,6 @@ int gpu_player_view_main(int argc, char *argv[]) {
wrapper_test_user_data_isolated_set(true);
widget_mplayer_test_isolated_set(true);
widget_render_profiler_test_isolated_set(true);
region_map_test_fow_persistence_set(false);
snprintf(VS(cpl.account), "%s", "renderer-fixture");
snprintf(VS(cpl.name), "%s", "Renderer Maintainer");
#endif
Expand Down Expand Up @@ -4884,7 +4881,6 @@ int gpu_player_view_main(int argc, char *argv[]) {
#ifdef ATRINIK_WIDGET_TESTS
widget_mplayer_test_isolated_set(false);
widget_render_profiler_test_isolated_set(false);
region_map_test_fow_persistence_set(true);
#endif
if (objects_ready) {
object_deinit();
Expand Down
4 changes: 4 additions & 0 deletions client/src/client/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,9 @@ int main(int argc, char *argv[]) {
return gpu_player_view_main(argc - 1, &argv[1]);
}

if (argc == 2 && strcmp(argv[1], "--region-exploration-test") == 0) {
return region_map_exploration_test() ? 0 : 1;
}
if (argc == 2 && strcmp(argv[1], "--access-lifecycle-test") == 0) {
return client_access_lifecycle_test() ? EXIT_SUCCESS : EXIT_FAILURE;
}
Expand Down Expand Up @@ -1309,6 +1312,7 @@ int main(int argc, char *argv[]) {

DoClient();
image_face_requests_service();
region_map_exploration_service();
}

/* If not connected, walk through connection chain and/or wait for
Expand Down
Loading