define switch subcommand structure

This commit is contained in:
Martin Michelsen
2022-04-03 17:54:46 -07:00
parent fe9eceed5c
commit 1d70933c17
7 changed files with 59 additions and 38 deletions
+1 -1
View File
@@ -43,7 +43,7 @@ Client::Client(
infinite_tp(false),
switch_assist(false),
can_chat(true) {
memset(&this->last_switch_enabled_subcommand, 0, sizeof(this->last_switch_enabled_subcommand));
this->last_switch_enabled_command.subcommand = 0;
int fd = bufferevent_getfd(this->bev);
if (fd < 0) {
this->is_virtual_connection = true;
+2 -16
View File
@@ -10,6 +10,7 @@
#include "Text.hh"
#include "PSOProtocol.hh"
#include "CommandFormats.hh"
@@ -26,21 +27,6 @@ enum class ServerBehavior {
PROXY_SERVER,
};
struct ClientConfig {
uint64_t magic;
uint8_t bb_game_state;
uint8_t bb_player_index;
uint16_t flags;
uint32_t proxy_destination_address;
uint16_t proxy_destination_port;
parray<uint8_t, 0x0E> unused;
} __attribute__((packed));
struct ClientConfigBB {
ClientConfig cfg;
parray<uint8_t, 0x08> unused;
} __attribute__((packed));
struct Client {
enum Flag {
// For patch server clients, client is Blue Burst rather than PC
@@ -120,7 +106,7 @@ struct Client {
bool infinite_hp; // cheats enabled
bool infinite_tp; // cheats enabled
bool switch_assist; // cheats enabled
std::string last_switch_enabled_subcommand;
G_SwitchStateChanged_6x05 last_switch_enabled_command;
bool can_chat;
std::string pending_bb_save_username;
uint8_t pending_bb_save_player_index;
+27 -5
View File
@@ -36,6 +36,26 @@
// This is the format of newserv's security data, which we call the client
// config. This data is opaque to the client, so this structure is not
// technically part of the PSO protocol.
struct ClientConfig {
uint64_t magic;
uint8_t bb_game_state;
uint8_t bb_player_index;
uint16_t flags;
uint32_t proxy_destination_address;
uint16_t proxy_destination_port;
parray<uint8_t, 0x0E> unused;
} __attribute__((packed));
struct ClientConfigBB {
ClientConfig cfg;
parray<uint8_t, 0x08> unused;
} __attribute__((packed));
// 00: Invalid command
// 01 (S->C): Lobby message box
@@ -1222,11 +1242,13 @@ struct G_ItemSubcommand {
// TODO: make last_switch_enabled_subcommand in both Client and Proxy use this
// when it's available
// struct G_SwitchStateChanged_6x05 {
// uint8_t subcommand;
// uint8_t size;
// TODO;
// };
struct G_SwitchStateChanged_6x05 {
uint8_t subcommand;
uint8_t size;
parray<uint8_t, 8> unknown; // includes switch ID
uint8_t area;
uint8_t enabled;
};
// 06: Send guild card
+11 -6
View File
@@ -646,13 +646,18 @@ bool process_client_60_62_6C_6D_C9_CB<void>(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
check_implemented_subcommand(session.id, data);
if (!data.empty() && (data[0] == 0x05) && (data[data.size() - 1] == 0x01) && session.enable_switch_assist) {
if (!session.last_switch_enabled_subcommand.empty()) {
session.log(WARNING, "Switch assist: replaying previous enable subcommand");
session.send_to_end(true, 0x60, 0x00, session.last_switch_enabled_subcommand);
session.send_to_end(false, 0x60, 0x00, session.last_switch_enabled_subcommand);
if (!data.empty() && (data[0] == 0x05) && session.enable_switch_assist) {
auto& cmd = check_size_t<G_SwitchStateChanged_6x05>(data);
if (cmd.enabled) {
if (session.last_switch_enabled_command.subcommand == 0x05) {
session.log(INFO, "Switch assist: replaying previous enable command");
session.send_to_end(true, 0x60, 0x00, &session.last_switch_enabled_command,
sizeof(session.last_switch_enabled_command));
session.send_to_end(false, 0x60, 0x00, &session.last_switch_enabled_command,
sizeof(session.last_switch_enabled_command));
}
session.last_switch_enabled_command = cmd;
}
session.last_switch_enabled_subcommand = data;
}
return true;
+3 -1
View File
@@ -375,7 +375,9 @@ ProxyServer::LinkedSession::LinkedSession(
override_lobby_event(-1),
override_lobby_number(-1),
lobby_players(12),
lobby_client_id(0) { }
lobby_client_id(0) {
this->last_switch_enabled_command.subcommand = 0;
}
ProxyServer::LinkedSession::LinkedSession(
ProxyServer* server,
+1 -1
View File
@@ -58,7 +58,7 @@ public:
bool enable_chat_filter;
bool enable_switch_assist;
bool save_files;
std::string last_switch_enabled_subcommand;
G_SwitchStateChanged_6x05 last_switch_enabled_command;
int16_t override_section_id;
int16_t override_lobby_event;
int16_t override_lobby_number;
+14 -8
View File
@@ -59,7 +59,7 @@ const PSOSubcommand* check_size_sc<PSOSubcommand>(
static void forward_subcommand(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint8_t command, uint8_t flag, const string& data) {
uint8_t command, uint8_t flag, const void* data, size_t size) {
// if the command is an Ep3-only command, make sure an Ep3 client sent it
bool command_is_ep3 = (command & 0xF0) == 0xC0;
@@ -90,11 +90,16 @@ static void forward_subcommand(shared_ptr<Lobby> l, shared_ptr<Client> c,
}
} else {
send_command_excluding_client(l, c, command, flag, data.data(), data.size());
send_command_excluding_client(l, c, command, flag, data, size);
}
}
}
static void forward_subcommand(shared_ptr<Lobby> l, shared_ptr<Client> c,
uint8_t command, uint8_t flag, const string& data) {
forward_subcommand(l, c, command, flag, data.data(), data.size());
}
////////////////////////////////////////////////////////////////////////////////
@@ -204,19 +209,20 @@ static void process_subcommand_use_technique(shared_ptr<ServerState>,
static void process_subcommand_switch_state_changed(shared_ptr<ServerState>,
shared_ptr<Lobby> l, shared_ptr<Client> c, uint8_t command, uint8_t flag,
const string& data) {
const auto* p = check_size_sc(data, 0x0C);
auto& cmd = check_size_t<G_SwitchStateChanged_6x05>(data);
if (!l->is_game()) {
return;
}
forward_subcommand(l, c, command, flag, data);
if (p[2].byte[3] == 1) { // If this is a switch enable command
if (cmd.enabled) {
if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->switch_assist &&
!c->last_switch_enabled_subcommand.empty()) {
(c->last_switch_enabled_command.subcommand == 0x05)) {
log(INFO, "[Switch assist] Replaying previous enable command");
forward_subcommand(l, c, command, flag, c->last_switch_enabled_subcommand);
send_command(c, command, flag, c->last_switch_enabled_subcommand);
forward_subcommand(l, c, command, flag, &c->last_switch_enabled_command,
sizeof(c->last_switch_enabled_command));
send_command(c, command, flag, c->last_switch_enabled_command);
}
memcpy(&c->last_switch_enabled_subcommand, p, sizeof(c->last_switch_enabled_subcommand));
c->last_switch_enabled_command = cmd;
}
}