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>,
|
||||
ProxyServer::LinkedSession& session, const std::u16string&) {
|
||||
string msg = string_printf("$C7GC: $C6%" PRId64 "$C7\nSlots: ",
|
||||
session.remote_guild_card_number);
|
||||
string msg;
|
||||
// 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++) {
|
||||
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");
|
||||
}
|
||||
} else {
|
||||
session.close_on_disconnect = true;
|
||||
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY;
|
||||
session.send_to_game_server();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ static HandlerResult S_invalid(shared_ptr<ServerState>,
|
||||
|
||||
static HandlerResult C_05(shared_ptr<ServerState>,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
// going to the remote server's ship/block select menu
|
||||
session.send_to_game_server();
|
||||
session.close_on_disconnect = true;
|
||||
session.disconnect_action = ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY;
|
||||
return HandlerResult::Type::SUPPRESS;
|
||||
}
|
||||
|
||||
|
||||
+19
-5
@@ -475,7 +475,7 @@ ProxyServer::LinkedSession::LinkedSession(
|
||||
TerminalFormat::FG_YELLOW,
|
||||
TerminalFormat::FG_RED),
|
||||
local_port(local_port),
|
||||
close_on_disconnect(false),
|
||||
disconnect_action(DisconnectAction::LONG_TIMEOUT),
|
||||
remote_ip_crc(0),
|
||||
enable_remote_ip_crc_patch(false),
|
||||
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->disconnect();
|
||||
if (session->close_on_disconnect) {
|
||||
if (session->disconnect_action == ProxyServer::LinkedSession::DisconnectAction::CLOSE_IMMEDIATELY) {
|
||||
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) {
|
||||
// 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
|
||||
for (size_t x = 0; x < this->lobby_players.size(); x++) {
|
||||
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->close_on_disconnect = true;
|
||||
this->disconnect_action = DisconnectAction::CLOSE_IMMEDIATELY;
|
||||
}
|
||||
}
|
||||
|
||||
void ProxyServer::LinkedSession::disconnect() {
|
||||
// Forward the disconnection to the other end
|
||||
// Disconnect both ends
|
||||
this->client_channel.disconnect();
|
||||
this->server_channel.disconnect();
|
||||
|
||||
// Set a timeout to delete the session entirely (in case the client doesn't
|
||||
// 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);
|
||||
event_add(this->timeout_event.get(), &tv);
|
||||
}
|
||||
|
||||
+7
-1
@@ -46,7 +46,13 @@ public:
|
||||
Channel server_channel;
|
||||
uint16_t local_port;
|
||||
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];
|
||||
uint32_t remote_ip_crc;
|
||||
|
||||
Reference in New Issue
Block a user