define switch subcommand structure
This commit is contained in:
+1
-1
@@ -43,7 +43,7 @@ Client::Client(
|
|||||||
infinite_tp(false),
|
infinite_tp(false),
|
||||||
switch_assist(false),
|
switch_assist(false),
|
||||||
can_chat(true) {
|
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);
|
int fd = bufferevent_getfd(this->bev);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
this->is_virtual_connection = true;
|
this->is_virtual_connection = true;
|
||||||
|
|||||||
+2
-16
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "Text.hh"
|
#include "Text.hh"
|
||||||
#include "PSOProtocol.hh"
|
#include "PSOProtocol.hh"
|
||||||
|
#include "CommandFormats.hh"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -26,21 +27,6 @@ enum class ServerBehavior {
|
|||||||
PROXY_SERVER,
|
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 {
|
struct Client {
|
||||||
enum Flag {
|
enum Flag {
|
||||||
// For patch server clients, client is Blue Burst rather than PC
|
// For patch server clients, client is Blue Burst rather than PC
|
||||||
@@ -120,7 +106,7 @@ struct Client {
|
|||||||
bool infinite_hp; // cheats enabled
|
bool infinite_hp; // cheats enabled
|
||||||
bool infinite_tp; // cheats enabled
|
bool infinite_tp; // cheats enabled
|
||||||
bool switch_assist; // cheats enabled
|
bool switch_assist; // cheats enabled
|
||||||
std::string last_switch_enabled_subcommand;
|
G_SwitchStateChanged_6x05 last_switch_enabled_command;
|
||||||
bool can_chat;
|
bool can_chat;
|
||||||
std::string pending_bb_save_username;
|
std::string pending_bb_save_username;
|
||||||
uint8_t pending_bb_save_player_index;
|
uint8_t pending_bb_save_player_index;
|
||||||
|
|||||||
+27
-5
@@ -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
|
// 00: Invalid command
|
||||||
|
|
||||||
// 01 (S->C): Lobby message box
|
// 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
|
// TODO: make last_switch_enabled_subcommand in both Client and Proxy use this
|
||||||
// when it's available
|
// when it's available
|
||||||
// struct G_SwitchStateChanged_6x05 {
|
struct G_SwitchStateChanged_6x05 {
|
||||||
// uint8_t subcommand;
|
uint8_t subcommand;
|
||||||
// uint8_t size;
|
uint8_t size;
|
||||||
// TODO;
|
parray<uint8_t, 8> unknown; // includes switch ID
|
||||||
// };
|
uint8_t area;
|
||||||
|
uint8_t enabled;
|
||||||
|
};
|
||||||
|
|
||||||
// 06: Send guild card
|
// 06: Send guild card
|
||||||
|
|
||||||
|
|||||||
+11
-6
@@ -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) {
|
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string& data) {
|
||||||
check_implemented_subcommand(session.id, data);
|
check_implemented_subcommand(session.id, data);
|
||||||
|
|
||||||
if (!data.empty() && (data[0] == 0x05) && (data[data.size() - 1] == 0x01) && session.enable_switch_assist) {
|
if (!data.empty() && (data[0] == 0x05) && session.enable_switch_assist) {
|
||||||
if (!session.last_switch_enabled_subcommand.empty()) {
|
auto& cmd = check_size_t<G_SwitchStateChanged_6x05>(data);
|
||||||
session.log(WARNING, "Switch assist: replaying previous enable subcommand");
|
if (cmd.enabled) {
|
||||||
session.send_to_end(true, 0x60, 0x00, session.last_switch_enabled_subcommand);
|
if (session.last_switch_enabled_command.subcommand == 0x05) {
|
||||||
session.send_to_end(false, 0x60, 0x00, session.last_switch_enabled_subcommand);
|
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;
|
return true;
|
||||||
|
|||||||
+3
-1
@@ -375,7 +375,9 @@ ProxyServer::LinkedSession::LinkedSession(
|
|||||||
override_lobby_event(-1),
|
override_lobby_event(-1),
|
||||||
override_lobby_number(-1),
|
override_lobby_number(-1),
|
||||||
lobby_players(12),
|
lobby_players(12),
|
||||||
lobby_client_id(0) { }
|
lobby_client_id(0) {
|
||||||
|
this->last_switch_enabled_command.subcommand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
ProxyServer::LinkedSession::LinkedSession(
|
ProxyServer::LinkedSession::LinkedSession(
|
||||||
ProxyServer* server,
|
ProxyServer* server,
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ public:
|
|||||||
bool enable_chat_filter;
|
bool enable_chat_filter;
|
||||||
bool enable_switch_assist;
|
bool enable_switch_assist;
|
||||||
bool save_files;
|
bool save_files;
|
||||||
std::string last_switch_enabled_subcommand;
|
G_SwitchStateChanged_6x05 last_switch_enabled_command;
|
||||||
int16_t override_section_id;
|
int16_t override_section_id;
|
||||||
int16_t override_lobby_event;
|
int16_t override_lobby_event;
|
||||||
int16_t override_lobby_number;
|
int16_t override_lobby_number;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ const PSOSubcommand* check_size_sc<PSOSubcommand>(
|
|||||||
|
|
||||||
|
|
||||||
static void forward_subcommand(shared_ptr<Lobby> l, shared_ptr<Client> c,
|
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
|
// if the command is an Ep3-only command, make sure an Ep3 client sent it
|
||||||
bool command_is_ep3 = (command & 0xF0) == 0xC0;
|
bool command_is_ep3 = (command & 0xF0) == 0xC0;
|
||||||
@@ -90,11 +90,16 @@ static void forward_subcommand(shared_ptr<Lobby> l, shared_ptr<Client> c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} 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>,
|
static void process_subcommand_switch_state_changed(shared_ptr<ServerState>,
|
||||||
shared_ptr<Lobby> l, shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
shared_ptr<Lobby> l, shared_ptr<Client> c, uint8_t command, uint8_t flag,
|
||||||
const string& data) {
|
const string& data) {
|
||||||
const auto* p = check_size_sc(data, 0x0C);
|
auto& cmd = check_size_t<G_SwitchStateChanged_6x05>(data);
|
||||||
if (!l->is_game()) {
|
if (!l->is_game()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
forward_subcommand(l, c, command, flag, data);
|
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 &&
|
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");
|
log(INFO, "[Switch assist] Replaying previous enable command");
|
||||||
forward_subcommand(l, c, command, flag, c->last_switch_enabled_subcommand);
|
forward_subcommand(l, c, command, flag, &c->last_switch_enabled_command,
|
||||||
send_command(c, command, flag, c->last_switch_enabled_subcommand);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user