fix BB data server proxy behavior
This commit is contained in:
+10
-3
@@ -150,8 +150,15 @@ static void server_command_lobby_info(shared_ptr<ServerState>, shared_ptr<Lobby>
|
|||||||
|
|
||||||
static void proxy_command_lobby_info(shared_ptr<ServerState>,
|
static void proxy_command_lobby_info(shared_ptr<ServerState>,
|
||||||
ProxyServer::LinkedSession& session, const std::u16string&) {
|
ProxyServer::LinkedSession& session, const std::u16string&) {
|
||||||
string msg = string_printf("$C7GC: $C6%" PRId64 "$C7\nSlots: ",
|
string msg;
|
||||||
session.remote_guild_card_number);
|
// On non-masked-GC sessions (BB), there is no remote Guild Card number, so we
|
||||||
|
// don't show it. (The user can see it in the pause menu, unlike in masked-GC
|
||||||
|
// sessions like GC.)
|
||||||
|
if (session.remote_guild_card_number >= 0) {
|
||||||
|
msg = string_printf("$C7GC: $C6%" PRId64 "$C7\n",
|
||||||
|
session.remote_guild_card_number);
|
||||||
|
}
|
||||||
|
msg += "Slots: ";
|
||||||
|
|
||||||
for (size_t z = 0; z < session.lobby_players.size(); z++) {
|
for (size_t z = 0; z < session.lobby_players.size(); z++) {
|
||||||
bool is_self = z == session.lobby_client_id;
|
bool is_self = z == session.lobby_client_id;
|
||||||
@@ -324,7 +331,7 @@ static void proxy_command_exit(shared_ptr<ServerState>,
|
|||||||
send_text_message(session.client_channel, u"$C6You must return to\nthe lobby first");
|
send_text_message(session.client_channel, u"$C6You must return to\nthe lobby first");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
session.close_on_disconnect = true;
|
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY;
|
||||||
session.send_to_game_server();
|
session.send_to_game_server();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ static HandlerResult S_invalid(shared_ptr<ServerState>,
|
|||||||
|
|
||||||
static HandlerResult C_05(shared_ptr<ServerState>,
|
static HandlerResult C_05(shared_ptr<ServerState>,
|
||||||
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
|
||||||
session.close_on_disconnect = true;
|
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::SHORT_TIMEOUT;
|
||||||
return HandlerResult::Type::FORWARD;
|
return HandlerResult::Type::FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1662,7 +1662,7 @@ static HandlerResult C_V123_A0_A1(shared_ptr<ServerState>,
|
|||||||
// For licensed sessions, send them back to newserv's main menu instead of
|
// For licensed sessions, send them back to newserv's main menu instead of
|
||||||
// going to the remote server's ship/block select menu
|
// going to the remote server's ship/block select menu
|
||||||
session.send_to_game_server();
|
session.send_to_game_server();
|
||||||
session.close_on_disconnect = true;
|
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY;
|
||||||
return HandlerResult::Type::SUPPRESS;
|
return HandlerResult::Type::SUPPRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+19
-5
@@ -475,7 +475,7 @@ ProxyServer::LinkedSession::LinkedSession(
|
|||||||
TerminalFormat::FG_YELLOW,
|
TerminalFormat::FG_YELLOW,
|
||||||
TerminalFormat::FG_RED),
|
TerminalFormat::FG_RED),
|
||||||
local_port(local_port),
|
local_port(local_port),
|
||||||
close_on_disconnect(false),
|
disconnect_action(DisconnectAction::LONG_TIMEOUT),
|
||||||
remote_ip_crc(0),
|
remote_ip_crc(0),
|
||||||
enable_remote_ip_crc_patch(false),
|
enable_remote_ip_crc_patch(false),
|
||||||
version(version),
|
version(version),
|
||||||
@@ -672,7 +672,7 @@ void ProxyServer::LinkedSession::on_error(Channel& ch, short events) {
|
|||||||
session->send_to_game_server("The server has\ndisconnected.");
|
session->send_to_game_server("The server has\ndisconnected.");
|
||||||
}
|
}
|
||||||
session->disconnect();
|
session->disconnect();
|
||||||
if (session->close_on_disconnect) {
|
if (session->disconnect_action == ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY) {
|
||||||
session->server->delete_session(session->id);
|
session->server->delete_session(session->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -685,6 +685,19 @@ void ProxyServer::LinkedSession::clear_lobby_players(size_t num_slots) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) {
|
void ProxyServer::LinkedSession::send_to_game_server(const char* error_message) {
|
||||||
|
// If there is no license, do nothing - we can't return to the game server
|
||||||
|
// from unlicensed sessions
|
||||||
|
if (!this->license) {
|
||||||
|
this->disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// On BB, do nothing - we can't return to the game server since the remote
|
||||||
|
// server likely sent different game data than what newserv would have sent
|
||||||
|
if (this->version == GameVersion::BB) {
|
||||||
|
this->disconnect();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Delete all the other players
|
// Delete all the other players
|
||||||
for (size_t x = 0; x < this->lobby_players.size(); x++) {
|
for (size_t x = 0; x < this->lobby_players.size(); x++) {
|
||||||
if (this->lobby_players[x].guild_card_number == 0) {
|
if (this->lobby_players[x].guild_card_number == 0) {
|
||||||
@@ -741,18 +754,19 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd));
|
this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd));
|
||||||
this->close_on_disconnect = true;
|
this->disconnect_action = DisconnectAction::CLOSE_IMMEDIATELY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyServer::LinkedSession::disconnect() {
|
void ProxyServer::LinkedSession::disconnect() {
|
||||||
// Forward the disconnection to the other end
|
// Disconnect both ends
|
||||||
this->client_channel.disconnect();
|
this->client_channel.disconnect();
|
||||||
this->server_channel.disconnect();
|
this->server_channel.disconnect();
|
||||||
|
|
||||||
// Set a timeout to delete the session entirely (in case the client doesn't
|
// Set a timeout to delete the session entirely (in case the client doesn't
|
||||||
// reconnect)
|
// reconnect)
|
||||||
struct timeval tv = usecs_to_timeval(this->license.get()
|
bool use_long_timeout = (this->license.get() && (this->disconnect_action == DisconnectAction::LONG_TIMEOUT));
|
||||||
|
struct timeval tv = usecs_to_timeval(use_long_timeout
|
||||||
? LICENSED_SESSION_TIMEOUT_USECS : UNLICENSED_SESSION_TIMEOUT_USECS);
|
? LICENSED_SESSION_TIMEOUT_USECS : UNLICENSED_SESSION_TIMEOUT_USECS);
|
||||||
event_add(this->timeout_event.get(), &tv);
|
event_add(this->timeout_event.get(), &tv);
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-1
@@ -46,7 +46,13 @@ public:
|
|||||||
Channel server_channel;
|
Channel server_channel;
|
||||||
uint16_t local_port;
|
uint16_t local_port;
|
||||||
struct sockaddr_storage next_destination;
|
struct sockaddr_storage next_destination;
|
||||||
bool close_on_disconnect;
|
|
||||||
|
enum class DisconnectAction {
|
||||||
|
LONG_TIMEOUT = 0,
|
||||||
|
SHORT_TIMEOUT,
|
||||||
|
CLOSE_IMMEDIATELY,
|
||||||
|
};
|
||||||
|
DisconnectAction disconnect_action;
|
||||||
|
|
||||||
uint8_t prev_server_command_bytes[6];
|
uint8_t prev_server_command_bytes[6];
|
||||||
uint32_t remote_ip_crc;
|
uint32_t remote_ip_crc;
|
||||||
|
|||||||
Reference in New Issue
Block a user