only return clients to newserv from proxy if not in a game
This commit is contained in:
+13
-5
@@ -902,6 +902,7 @@ static HandlerResult on_server_65_67_68(shared_ptr<ServerState>,
|
|||||||
session.lobby_players.clear();
|
session.lobby_players.clear();
|
||||||
session.lobby_players.resize(12);
|
session.lobby_players.resize(12);
|
||||||
session.log.info("Cleared lobby players");
|
session.log.info("Cleared lobby players");
|
||||||
|
session.is_in_game = false;
|
||||||
|
|
||||||
// This command can cause the client to no longer send D6 responses when
|
// This command can cause the client to no longer send D6 responses when
|
||||||
// 1A/D5 large message boxes are closed. newserv keeps track of this
|
// 1A/D5 large message boxes are closed. newserv keeps track of this
|
||||||
@@ -957,6 +958,7 @@ static HandlerResult on_server_64(shared_ptr<ServerState>,
|
|||||||
// overwrite all 4 entries for this command
|
// overwrite all 4 entries for this command
|
||||||
session.lobby_players.resize(4);
|
session.lobby_players.resize(4);
|
||||||
session.log.info("Cleared lobby players");
|
session.log.info("Cleared lobby players");
|
||||||
|
session.is_in_game = true;
|
||||||
|
|
||||||
CmdT* cmd;
|
CmdT* cmd;
|
||||||
S_JoinGame_GC_Ep3_64* cmd_ep3 = nullptr;
|
S_JoinGame_GC_Ep3_64* cmd_ep3 = nullptr;
|
||||||
@@ -1020,6 +1022,12 @@ static HandlerResult on_server_66_69(shared_ptr<ServerState>,
|
|||||||
return HandlerResult::Type::FORWARD;
|
return HandlerResult::Type::FORWARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HandlerResult on_client_98(shared_ptr<ServerState>,
|
||||||
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
|
||||||
|
session.is_in_game = false;
|
||||||
|
return HandlerResult::Type::FORWARD;
|
||||||
|
}
|
||||||
|
|
||||||
static HandlerResult on_client_06(shared_ptr<ServerState> s,
|
static HandlerResult on_client_06(shared_ptr<ServerState> s,
|
||||||
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||||
if (data.size() >= 12) {
|
if (data.size() >= 12) {
|
||||||
@@ -1611,7 +1619,7 @@ static on_command_t handlers[6][0x100][2] = {
|
|||||||
/* 95 */ {nullptr, nullptr},
|
/* 95 */ {nullptr, nullptr},
|
||||||
/* 96 */ {nullptr, nullptr},
|
/* 96 */ {nullptr, nullptr},
|
||||||
/* 97 */ {on_server_97, nullptr},
|
/* 97 */ {on_server_97, nullptr},
|
||||||
/* 98 */ {nullptr, nullptr},
|
/* 98 */ {nullptr, on_client_98},
|
||||||
/* 99 */ {nullptr, nullptr},
|
/* 99 */ {nullptr, nullptr},
|
||||||
/* 9A */ {nullptr, nullptr},
|
/* 9A */ {nullptr, nullptr},
|
||||||
/* 9B */ {nullptr, nullptr},
|
/* 9B */ {nullptr, nullptr},
|
||||||
@@ -1877,7 +1885,7 @@ static on_command_t handlers[6][0x100][2] = {
|
|||||||
/* 95 */ {nullptr, nullptr},
|
/* 95 */ {nullptr, nullptr},
|
||||||
/* 96 */ {nullptr, nullptr},
|
/* 96 */ {nullptr, nullptr},
|
||||||
/* 97 */ {on_server_97, nullptr},
|
/* 97 */ {on_server_97, nullptr},
|
||||||
/* 98 */ {nullptr, nullptr},
|
/* 98 */ {nullptr, on_client_98},
|
||||||
/* 99 */ {nullptr, nullptr},
|
/* 99 */ {nullptr, nullptr},
|
||||||
/* 9A */ {nullptr, nullptr},
|
/* 9A */ {nullptr, nullptr},
|
||||||
/* 9B */ {nullptr, nullptr},
|
/* 9B */ {nullptr, nullptr},
|
||||||
@@ -2143,7 +2151,7 @@ static on_command_t handlers[6][0x100][2] = {
|
|||||||
/* 95 */ {nullptr, nullptr},
|
/* 95 */ {nullptr, nullptr},
|
||||||
/* 96 */ {nullptr, nullptr},
|
/* 96 */ {nullptr, nullptr},
|
||||||
/* 97 */ {on_server_97, nullptr},
|
/* 97 */ {on_server_97, nullptr},
|
||||||
/* 98 */ {nullptr, nullptr},
|
/* 98 */ {nullptr, on_client_98},
|
||||||
/* 99 */ {nullptr, nullptr},
|
/* 99 */ {nullptr, nullptr},
|
||||||
/* 9A */ {on_server_gc_9A, nullptr},
|
/* 9A */ {on_server_gc_9A, nullptr},
|
||||||
/* 9B */ {nullptr, nullptr},
|
/* 9B */ {nullptr, nullptr},
|
||||||
@@ -2409,7 +2417,7 @@ static on_command_t handlers[6][0x100][2] = {
|
|||||||
/* 95 */ {nullptr, nullptr},
|
/* 95 */ {nullptr, nullptr},
|
||||||
/* 96 */ {nullptr, nullptr},
|
/* 96 */ {nullptr, nullptr},
|
||||||
/* 97 */ {on_server_97, nullptr},
|
/* 97 */ {on_server_97, nullptr},
|
||||||
/* 98 */ {nullptr, nullptr},
|
/* 98 */ {nullptr, on_client_98},
|
||||||
/* 99 */ {nullptr, nullptr},
|
/* 99 */ {nullptr, nullptr},
|
||||||
/* 9A */ {nullptr, nullptr},
|
/* 9A */ {nullptr, nullptr},
|
||||||
/* 9B */ {nullptr, nullptr},
|
/* 9B */ {nullptr, nullptr},
|
||||||
@@ -2675,7 +2683,7 @@ static on_command_t handlers[6][0x100][2] = {
|
|||||||
/* 95 */ {nullptr, nullptr},
|
/* 95 */ {nullptr, nullptr},
|
||||||
/* 96 */ {nullptr, nullptr},
|
/* 96 */ {nullptr, nullptr},
|
||||||
/* 97 */ {nullptr, nullptr},
|
/* 97 */ {nullptr, nullptr},
|
||||||
/* 98 */ {nullptr, nullptr},
|
/* 98 */ {nullptr, on_client_98},
|
||||||
/* 99 */ {nullptr, nullptr},
|
/* 99 */ {nullptr, nullptr},
|
||||||
/* 9A */ {nullptr, nullptr},
|
/* 9A */ {nullptr, nullptr},
|
||||||
/* 9B */ {nullptr, nullptr},
|
/* 9B */ {nullptr, nullptr},
|
||||||
|
|||||||
+47
-38
@@ -487,7 +487,8 @@ ProxyServer::LinkedSession::LinkedSession(
|
|||||||
override_lobby_number(-1),
|
override_lobby_number(-1),
|
||||||
lobby_players(12),
|
lobby_players(12),
|
||||||
lobby_client_id(0),
|
lobby_client_id(0),
|
||||||
leader_client_id(0) {
|
leader_client_id(0),
|
||||||
|
is_in_game(false) {
|
||||||
this->last_switch_enabled_command.subcommand = 0;
|
this->last_switch_enabled_command.subcommand = 0;
|
||||||
memset(this->prev_server_command_bytes, 0, sizeof(this->prev_server_command_bytes));
|
memset(this->prev_server_command_bytes, 0, sizeof(this->prev_server_command_bytes));
|
||||||
}
|
}
|
||||||
@@ -670,49 +671,57 @@ void ProxyServer::LinkedSession::send_to_game_server(const char* error_message)
|
|||||||
uint8_t leaving_id = x;
|
uint8_t leaving_id = x;
|
||||||
uint8_t leader_id = this->lobby_client_id;
|
uint8_t leader_id = this->lobby_client_id;
|
||||||
S_LeaveLobby_66_69_Ep3_E9 cmd = {leaving_id, leader_id, 1, 0};
|
S_LeaveLobby_66_69_Ep3_E9 cmd = {leaving_id, leader_id, 1, 0};
|
||||||
this->client_channel.send(0x69, leaving_id, &cmd, sizeof(cmd));
|
this->client_channel.send(this->is_in_game ? 0x66 : 0x69, leaving_id, &cmd, sizeof(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
string encoded_name = encode_sjis(this->server->state->name);
|
string encoded_name = encode_sjis(this->server->state->name);
|
||||||
send_ship_info(this->client_channel, decode_sjis(string_printf(
|
if (this->is_in_game) {
|
||||||
"You\'ve returned to\n\tC6%s$C7\n\n%s", encoded_name.c_str(),
|
send_ship_info(this->client_channel, decode_sjis(string_printf(
|
||||||
error_message ? error_message : "")));
|
"You cannot return\nto $C6%s$C7\nwhile in a game.\n\n%s",
|
||||||
|
encoded_name.c_str(), error_message ? error_message : "")));
|
||||||
|
this->disconnect();
|
||||||
|
|
||||||
// Restore newserv_client_config, so the login server gets the client flags
|
|
||||||
S_UpdateClientConfig_DC_PC_V3_04 update_client_config_cmd;
|
|
||||||
update_client_config_cmd.player_tag = 0x00010000;
|
|
||||||
update_client_config_cmd.guild_card_number = this->license->serial_number;
|
|
||||||
update_client_config_cmd.cfg = this->newserv_client_config.cfg;
|
|
||||||
this->client_channel.send(0x04, 0x00, &update_client_config_cmd, sizeof(update_client_config_cmd));
|
|
||||||
|
|
||||||
static const vector<string> version_to_port_name({
|
|
||||||
"bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"});
|
|
||||||
const auto& port_name = version_to_port_name.at(static_cast<size_t>(
|
|
||||||
this->version));
|
|
||||||
|
|
||||||
S_Reconnect_19 reconnect_cmd = {{
|
|
||||||
0, this->server->state->name_to_port_config.at(port_name)->port, 0}};
|
|
||||||
|
|
||||||
// If the client is on a virtual connection, we can use any address
|
|
||||||
// here and they should be able to connect back to the game server. If
|
|
||||||
// the client is on a real connection, we'll use the sockname of the
|
|
||||||
// existing connection (like we do in the server 19 command handler).
|
|
||||||
if (this->client_channel.is_virtual_connection) {
|
|
||||||
struct sockaddr_in* dest_sin = reinterpret_cast<struct sockaddr_in*>(&this->next_destination);
|
|
||||||
if (dest_sin->sin_family != AF_INET) {
|
|
||||||
throw logic_error("ss not AF_INET");
|
|
||||||
}
|
|
||||||
reconnect_cmd.address.store_raw(dest_sin->sin_addr.s_addr);
|
|
||||||
} else {
|
} else {
|
||||||
const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(
|
send_ship_info(this->client_channel, decode_sjis(string_printf(
|
||||||
&this->client_channel.local_addr);
|
"You\'ve returned to\n\tC6%s$C7\n\n%s", encoded_name.c_str(),
|
||||||
if (sin->sin_family != AF_INET) {
|
error_message ? error_message : "")));
|
||||||
throw logic_error("existing connection is not ipv4");
|
|
||||||
}
|
|
||||||
reconnect_cmd.address.store_raw(sin->sin_addr.s_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd));
|
// Restore newserv_client_config, so the login server gets the client flags
|
||||||
|
S_UpdateClientConfig_DC_PC_V3_04 update_client_config_cmd;
|
||||||
|
update_client_config_cmd.player_tag = 0x00010000;
|
||||||
|
update_client_config_cmd.guild_card_number = this->license->serial_number;
|
||||||
|
update_client_config_cmd.cfg = this->newserv_client_config.cfg;
|
||||||
|
this->client_channel.send(0x04, 0x00, &update_client_config_cmd, sizeof(update_client_config_cmd));
|
||||||
|
|
||||||
|
static const vector<string> version_to_port_name({
|
||||||
|
"bb-patch", "console-login", "pc-login", "console-login", "console-login", "bb-init"});
|
||||||
|
const auto& port_name = version_to_port_name.at(static_cast<size_t>(
|
||||||
|
this->version));
|
||||||
|
|
||||||
|
S_Reconnect_19 reconnect_cmd = {{
|
||||||
|
0, this->server->state->name_to_port_config.at(port_name)->port, 0}};
|
||||||
|
|
||||||
|
// If the client is on a virtual connection, we can use any address
|
||||||
|
// here and they should be able to connect back to the game server. If
|
||||||
|
// the client is on a real connection, we'll use the sockname of the
|
||||||
|
// existing connection (like we do in the server 19 command handler).
|
||||||
|
if (this->client_channel.is_virtual_connection) {
|
||||||
|
struct sockaddr_in* dest_sin = reinterpret_cast<struct sockaddr_in*>(&this->next_destination);
|
||||||
|
if (dest_sin->sin_family != AF_INET) {
|
||||||
|
throw logic_error("ss not AF_INET");
|
||||||
|
}
|
||||||
|
reconnect_cmd.address.store_raw(dest_sin->sin_addr.s_addr);
|
||||||
|
} else {
|
||||||
|
const struct sockaddr_in* sin = reinterpret_cast<const struct sockaddr_in*>(
|
||||||
|
&this->client_channel.local_addr);
|
||||||
|
if (sin->sin_family != AF_INET) {
|
||||||
|
throw logic_error("existing connection is not ipv4");
|
||||||
|
}
|
||||||
|
reconnect_cmd.address.store_raw(sin->sin_addr.s_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->client_channel.send(0x19, 0x00, &reconnect_cmd, sizeof(reconnect_cmd));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProxyServer::LinkedSession::disconnect() {
|
void ProxyServer::LinkedSession::disconnect() {
|
||||||
|
|||||||
@@ -82,6 +82,7 @@ public:
|
|||||||
std::vector<LobbyPlayer> lobby_players;
|
std::vector<LobbyPlayer> lobby_players;
|
||||||
size_t lobby_client_id;
|
size_t lobby_client_id;
|
||||||
size_t leader_client_id;
|
size_t leader_client_id;
|
||||||
|
bool is_in_game;
|
||||||
|
|
||||||
std::shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt;
|
std::shared_ptr<PSOBBMultiKeyDetectorEncryption> detector_crypt;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user