don't show programs menu if client has already saved
This commit is contained in:
@@ -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
@@ -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;
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user