don't show programs menu if client has already saved

This commit is contained in:
Martin Michelsen
2022-06-01 22:21:58 -07:00
parent 562bc4a40c
commit 5ae1fc78a9
7 changed files with 58 additions and 19 deletions
+1
View File
@@ -28,6 +28,7 @@ Client::Client(
bev(bev),
server_behavior(server_behavior),
should_disconnect(false),
should_send_to_lobby_server(false),
proxy_destination_address(0),
proxy_destination_port(0),
play_time_begin(now()),
+9 -6
View File
@@ -25,11 +25,10 @@ struct Client {
// After joining a lobby, client will no longer send D6 commands when they
// close message boxes
NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN = 0x0002,
// Client has the above flag and has already joined a lobby, or is Blue Burst
// (BB never sends D6 commands)
// Client has the above flag and has already joined a lobby, or is not GC
NO_MESSAGE_BOX_CLOSE_CONFIRMATION = 0x0004,
// Client is Episode 3, should be able to see CARD lobbies, and should only be
// able to see/join games with the IS_EPISODE_3 flag
// Client is Episode 3, should be able to see CARD lobbies, and should only
// be able to see/join games with the IS_EPISODE_3 flag
EPISODE_3 = 0x0008,
// Client is DC v1 (disables some features)
DCV1 = 0x0010,
@@ -43,10 +42,13 @@ struct Client {
AT_WELCOME_MESSAGE = 0x0100,
// Client disconnect if it receives B2 (send_function_call)
DOES_NOT_SUPPORT_SEND_FUNCTION_CALL = 0x0200,
// Client has already received a 97 (enable saves) command, so don't show
// the programs menu anymore
SAVE_ENABLED = 0x0400,
// TODO: Do DCv1 and PC support send_function_call? Here we assume they don't
DEFAULT_V1 = DCV1 | DOES_NOT_SUPPORT_SEND_FUNCTION_CALL,
DEFAULT_V2_DC = 0x0000,
DEFAULT_V1 = DCV1 | NO_MESSAGE_BOX_CLOSE_CONFIRMATION | DOES_NOT_SUPPORT_SEND_FUNCTION_CALL,
DEFAULT_V2_DC = NO_MESSAGE_BOX_CLOSE_CONFIRMATION,
DEFAULT_V2_PC = NO_MESSAGE_BOX_CLOSE_CONFIRMATION | DOES_NOT_SUPPORT_SEND_FUNCTION_CALL,
DEFAULT_V3_GC = 0x0000,
DEFAULT_V3_GC_PLUS = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | DOES_NOT_SUPPORT_SEND_FUNCTION_CALL,
@@ -76,6 +78,7 @@ struct Client {
ServerBehavior server_behavior;
bool is_virtual_connection;
bool should_disconnect;
bool should_send_to_lobby_server;
uint32_t proxy_destination_address;
uint16_t proxy_destination_port;
+1
View File
@@ -64,6 +64,7 @@ struct MenuItem {
BB_ONLY = INVISIBLE_ON_DC | INVISIBLE_ON_PC | INVISIBLE_ON_GC,
REQUIRES_MESSAGE_BOXES = 0x10,
REQUIRES_SEND_FUNCTION_CALL = 0x20,
REQUIRES_SAVE_DISABLED = 0x40,
};
uint32_t item_id;
+14 -3
View File
@@ -99,6 +99,17 @@ static bool process_default(shared_ptr<ServerState>,
return true;
}
static bool process_server_97(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
// Trap 97 commands and always send 97 01 04 00. (If flag is 0, the client
// triggers cheat protection and deletes a bunch of data.)
session.send_to_end(false, 0x97, 0x01);
// Also, update the newserv client config so we'll know not to show the
// programs menu if they return to newserv.
session.newserv_client_config.cfg.flags |= Client::Flag::SAVE_ENABLED;
return false;
}
static bool process_server_gc_9A(shared_ptr<ServerState>,
ProxyServer::LinkedSession& session, uint16_t, uint32_t, string&) {
if (!session.license) {
@@ -1022,7 +1033,7 @@ static process_command_t dc_server_handlers[0x100] = {
/* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, defh, defh, process_server_66_69, defh, defh, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh,
/* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, defh, defh, defh, defh, defh, defh,
/* A0 */ defh, defh, defh, defh, defh, defh, defh, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh,
/* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
@@ -1040,7 +1051,7 @@ static process_command_t pc_server_handlers[0x100] = {
/* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64<S_JoinGame_PC_64>, process_server_65_67_68<S_JoinLobby_PC_65_67_68>, process_server_66_69, process_server_65_67_68<S_JoinLobby_PC_65_67_68>, process_server_65_67_68<S_JoinLobby_PC_65_67_68>, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh,
/* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* 80 */ defh, defh, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, defh, defh, defh, defh, defh, defh,
/* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6<S_OpenFile_PC_GC_44_A6>, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh,
/* B0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* C0 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
@@ -1058,7 +1069,7 @@ static process_command_t gc_server_handlers[0x100] = {
/* 60 */ process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_64<S_JoinGame_GC_64>, process_server_65_67_68<S_JoinLobby_GC_65_67_68>, process_server_66_69, process_server_65_67_68<S_JoinLobby_GC_65_67_68>, process_server_65_67_68<S_JoinLobby_GC_65_67_68>, process_server_66_69, defh, defh, process_server_60_62_6C_6D_C9_CB, process_server_60_62_6C_6D_C9_CB, defh, defh,
/* 70 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, defh,
/* 80 */ defh, process_server_81<SC_SimpleMail_GC_81>, defh, defh, defh, defh, defh, defh, process_server_88, defh, defh, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, defh, defh, defh, process_server_gc_9A, defh, defh, defh, defh, defh,
/* 90 */ defh, defh, defh, defh, defh, defh, defh, process_server_97, defh, defh, process_server_gc_9A, defh, defh, defh, defh, defh,
/* A0 */ defh, defh, defh, defh, defh, defh, process_server_44_A6<S_OpenFile_PC_GC_44_A6>, process_server_13_A7, defh, defh, defh, defh, defh, defh, defh, defh,
/* B0 */ defh, defh, process_server_B2, defh, defh, defh, defh, defh, process_server_gc_B8, defh, defh, defh, defh, defh, defh, defh,
/* C0 */ defh, defh, defh, defh, process_server_C4<S_ChoiceSearchResultEntry_GC_C4>, defh, defh, defh, defh, process_server_60_62_6C_6D_C9_CB, defh, process_server_60_62_6C_6D_C9_CB, defh, defh, defh, defh,
+30 -8
View File
@@ -392,13 +392,29 @@ void process_return_client_config(shared_ptr<ServerState>, shared_ptr<Client> c,
void process_client_checksum(shared_ptr<ServerState>, shared_ptr<Client> c,
uint16_t, uint32_t, const string& data) { // 96
check_size_t<C_ClientChecksum_GC_96>(data);
send_command(c, 0x97, 0x01);
send_server_time(c);
}
void process_server_time_request(shared_ptr<ServerState>, shared_ptr<Client> c,
void process_server_time_request(shared_ptr<ServerState> s, shared_ptr<Client> c,
uint16_t, uint32_t, const string& data) { // B1
check_size_v(data.size(), 0);
send_server_time(c);
// The B1 command is sent in response to a 97 command, which is normally part
// of the pre-ship-select login sequence. However, newserv delays this until
// after the ship select menu so that loading a GameCube program doesn't cause
// the player's items to be deleted when they next play PSO. It's also not a
// good idea to send a 97 and 19 at the same time, because the memory card and
// BBA are on the same EXI bus on the GameCube and this seems to cause the SYN
// packet after a 19 to get dropped pretty often, which causes a delay in
// joining the lobby. This is why we delay the 19 command until the client
// responds after saving.
if (c->should_send_to_lobby_server) {
static const vector<string> version_to_port_name({
"dc-lobby", "pc-lobby", "bb-lobby", "gc-lobby", "bb-lobby"});
const auto& port_name = version_to_port_name.at(static_cast<size_t>(c->version));
send_reconnect(c, s->connect_address_for_client(c),
s->name_to_port_config.at(port_name)->port);
}
}
@@ -710,12 +726,18 @@ void process_menu_selection(shared_ptr<ServerState> s, shared_ptr<Client> c,
case MenuID::MAIN: {
switch (cmd.item_id) {
case MainMenuItemID::GO_TO_LOBBY: {
static const vector<string> version_to_port_name({
"dc-lobby", "pc-lobby", "bb-lobby", "gc-lobby", "bb-lobby"});
const auto& port_name = version_to_port_name.at(static_cast<size_t>(c->version));
send_reconnect(c, s->connect_address_for_client(c),
s->name_to_port_config.at(port_name)->port);
c->should_send_to_lobby_server = true;
if (!(c->flags & Client::Flag::SAVE_ENABLED)) {
send_command(c, 0x97, 0x01);
c->flags |= Client::Flag::SAVE_ENABLED;
send_update_client_config(c);
} else {
static const vector<string> version_to_port_name({
"dc-lobby", "pc-lobby", "bb-lobby", "gc-lobby", "bb-lobby"});
const auto& port_name = version_to_port_name.at(static_cast<size_t>(c->version));
send_reconnect(c, s->connect_address_for_client(c),
s->name_to_port_config.at(port_name)->port);
}
break;
}
+2 -1
View File
@@ -790,7 +790,8 @@ void send_menu_t(
((c->version == GameVersion::GC) && (item.flags & MenuItem::Flag::INVISIBLE_ON_GC)) ||
((c->version == GameVersion::BB) && (item.flags & MenuItem::Flag::INVISIBLE_ON_BB)) ||
((item.flags & MenuItem::Flag::REQUIRES_MESSAGE_BOXES) && (c->flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION)) ||
((item.flags & MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL) && (c->flags & Client::Flag::DOES_NOT_SUPPORT_SEND_FUNCTION_CALL))) {
((item.flags & MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL) && (c->flags & Client::Flag::DOES_NOT_SUPPORT_SEND_FUNCTION_CALL)) ||
((item.flags & MenuItem::Flag::REQUIRES_SAVE_DISABLED) && (c->flags & Client::Flag::SAVE_ENABLED))) {
continue;
}
auto& e = entries.emplace_back();
+1 -1
View File
@@ -337,7 +337,7 @@ void ServerState::create_menus(shared_ptr<const JSONObject> config_json) {
}
if (!this->dol_file_index->empty()) {
this->main_menu.emplace_back(MainMenuItemID::PROGRAMS, u"Programs",
u"Run GameCube\nprograms", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL);
u"Run GameCube\nprograms", MenuItem::Flag::GC_ONLY | MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL | MenuItem::Flag::REQUIRES_SAVE_DISABLED);
}
this->main_menu.emplace_back(MainMenuItemID::DISCONNECT, u"Disconnect",
u"Disconnect", 0);