Add server validation, profile store, session launch

Introduce server validation and a session launch flow with persistent server profiles.

- Add ConnectAndValidateServer to Networking to validate handshake/timeouts and return human-friendly errors; avoid auto-connecting in transform send path and remove unconditional local connect on startup.
- Add ServerProfileStore (header + implementation) to persist server->saveFile bindings under Documents/My Games/.../CommonwealthOnline/server-profiles.json with thread-safe load/save, lookup, touch and bind operations.
- Add SessionLaunch (header + implementation) to handle launching validated sessions, first-time join flow (auto coc to SanctuaryExt, character creation menus, save binding), F4SE message handling and periodic Update processing.
- Update ServerBrowserBridge to parse/validate ports, use ConnectAndValidateServer, display joinLoading UI events, schedule validated session launch on the game task thread, and centralize join success/failure handling.
- Wire SessionLaunch into main.cpp (update loop and F4SE message hook).
- Improve direct-connect UI in app.js with client-side validation, port parsing, and handling of joinLoading events.

These changes provide better connection validation, user feedback during joins, and automatic handling for first-time server joins with persistence of associated saves.
This commit is contained in:
2026-06-09 16:26:33 +12:00
parent e6748556ae
commit e61922678b
9 changed files with 963 additions and 47 deletions
+1
View File
@@ -8,6 +8,7 @@ namespace F4T::Networking
std::string GetLocalPlayerLogPrefix();
bool ConnectToServer(const char* a_host, std::uint16_t a_port);
bool ConnectToLocalServer();
bool ConnectAndValidateServer(const char* a_host, std::uint16_t a_port, std::string& a_error);
void DisconnectFromLocalServer();
bool IsConnectedToServer();
bool SendTransformPacket(
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
#include <optional>
#include <string>
namespace F4T::ServerProfileStore
{
std::string MakeServerKey(const std::string& a_host, std::uint16_t a_port);
bool HasProfile(const std::string& a_serverKey);
std::optional<std::string> LookupSaveFile(const std::string& a_serverKey);
void BindSaveFile(const std::string& a_serverKey, const std::string& a_saveFile);
void TouchProfile(const std::string& a_serverKey);
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include "F4TServerBrowserData.h"
namespace F4SE
{
class MessagingInterface;
}
namespace F4T::SessionLaunch
{
bool LaunchValidatedSession(const ServerBrowser::ServerEntry& a_entry, std::string& a_error);
void OnF4SEMessage(F4SE::MessagingInterface::Message* a_msg);
void Update();
void TryCompletePendingProfileBind();
}