diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 87cdca01..dc25610e 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -3950,14 +3950,30 @@ shared_ptr create_game_generic( case Version::DC_V1: case Version::DC_V2: case Version::PC_V2: - game->set_drop_mode(s->default_drop_mode_v1_v2); - game->allowed_drop_modes = s->allowed_drop_modes_v1_v2; + if (game->mode == GameMode::BATTLE) { + game->set_drop_mode(s->default_drop_mode_v1_v2_battle); + game->allowed_drop_modes = s->allowed_drop_modes_v1_v2_battle; + } else if (game->mode == GameMode::CHALLENGE) { + game->set_drop_mode(s->default_drop_mode_v1_v2_challenge); + game->allowed_drop_modes = s->allowed_drop_modes_v1_v2_challenge; + } else { + game->set_drop_mode(s->default_drop_mode_v1_v2_normal); + game->allowed_drop_modes = s->allowed_drop_modes_v1_v2_normal; + } break; case Version::GC_NTE: case Version::GC_V3: case Version::XB_V3: - game->set_drop_mode(s->default_drop_mode_v3); - game->allowed_drop_modes = s->allowed_drop_modes_v3; + if (game->mode == GameMode::BATTLE) { + game->set_drop_mode(s->default_drop_mode_v3_battle); + game->allowed_drop_modes = s->allowed_drop_modes_v3_battle; + } else if (game->mode == GameMode::CHALLENGE) { + game->set_drop_mode(s->default_drop_mode_v3_challenge); + game->allowed_drop_modes = s->allowed_drop_modes_v3_challenge; + } else { + game->set_drop_mode(s->default_drop_mode_v3_normal); + game->allowed_drop_modes = s->allowed_drop_modes_v3_normal; + } break; case Version::GC_EP3_TRIAL_EDITION: case Version::GC_EP3: @@ -3965,24 +3981,27 @@ shared_ptr create_game_generic( game->allowed_drop_modes = (1 << static_cast(game->drop_mode)); break; case Version::BB_V4: - // Disallow CLIENT mode on BB - if (s->default_drop_mode_v4 == Lobby::DropMode::CLIENT) { - // If the default is CLIENT (somehow), force it to be SERVER_SHARED - game->set_drop_mode(Lobby::DropMode::SERVER_SHARED); - game->allowed_drop_modes |= (1 << static_cast(game->drop_mode)); + if (game->mode == GameMode::BATTLE) { + game->set_drop_mode(s->default_drop_mode_v4_battle); + game->allowed_drop_modes = s->allowed_drop_modes_v4_battle; + } else if (game->mode == GameMode::CHALLENGE) { + game->set_drop_mode(s->default_drop_mode_v4_challenge); + game->allowed_drop_modes = s->allowed_drop_modes_v4_challenge; } else { - game->set_drop_mode(s->default_drop_mode_v4); - game->allowed_drop_modes = s->allowed_drop_modes_v4 & ~(1 << static_cast(Lobby::DropMode::CLIENT)); + game->set_drop_mode(s->default_drop_mode_v4_normal); + game->allowed_drop_modes = s->allowed_drop_modes_v4_normal; + } + // Disallow CLIENT mode on BB + if (game->drop_mode == Lobby::DropMode::CLIENT) { + throw logic_error("CLIENT mode not allowed on BB"); + } + if (game->allowed_drop_modes & (1 << static_cast(Lobby::DropMode::CLIENT))) { + throw logic_error("CLIENT mode not allowed on BB"); } break; default: throw logic_error("invalid quest script version"); } - // Only allow DISABLED in Normal; use the default in Battle/Challenge/Solo - if ((game->drop_mode == Lobby::DropMode::DISABLED) && (mode != GameMode::NORMAL)) { - game->set_drop_mode((game->base_version == Version::BB_V4) ? Lobby::DropMode::SERVER_SHARED : Lobby::DropMode::CLIENT); - game->allowed_drop_modes |= (1 << static_cast(game->drop_mode)); - } game->event = Lobby::game_event_for_lobby_event(current_lobby->event); game->block = 0xFF; diff --git a/src/ServerState.cc b/src/ServerState.cc index b80f72a0..fd064468 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -26,12 +26,24 @@ ServerState::ServerState(shared_ptr base, const string& confi allow_unregistered_users(false), allow_dc_pc_games(false), allow_gc_xb_games(true), - allowed_drop_modes_v1_v2(0xFF), - allowed_drop_modes_v3(0xFF), - allowed_drop_modes_v4(0xFD), // CLIENT not allowed - default_drop_mode_v1_v2(Lobby::DropMode::CLIENT), - default_drop_mode_v3(Lobby::DropMode::CLIENT), - default_drop_mode_v4(Lobby::DropMode::SERVER_SHARED), + allowed_drop_modes_v1_v2_normal(0x1F), + allowed_drop_modes_v1_v2_battle(0x07), + allowed_drop_modes_v1_v2_challenge(0x07), + allowed_drop_modes_v3_normal(0x1F), + allowed_drop_modes_v3_battle(0x07), + allowed_drop_modes_v3_challenge(0x07), + allowed_drop_modes_v4_normal(0x1D), // CLIENT not allowed + allowed_drop_modes_v4_battle(0x05), + allowed_drop_modes_v4_challenge(0x05), + default_drop_mode_v1_v2_normal(Lobby::DropMode::CLIENT), + default_drop_mode_v1_v2_battle(Lobby::DropMode::CLIENT), + default_drop_mode_v1_v2_challenge(Lobby::DropMode::CLIENT), + default_drop_mode_v3_normal(Lobby::DropMode::CLIENT), + default_drop_mode_v3_battle(Lobby::DropMode::CLIENT), + default_drop_mode_v3_challenge(Lobby::DropMode::CLIENT), + default_drop_mode_v4_normal(Lobby::DropMode::SERVER_SHARED), + default_drop_mode_v4_battle(Lobby::DropMode::SERVER_SHARED), + default_drop_mode_v4_challenge(Lobby::DropMode::SERVER_SHARED), persistent_game_idle_timeout_usecs(0), ep3_send_function_call_enabled(false), catch_handler_exceptions(true), @@ -631,16 +643,31 @@ void ServerState::parse_config(const JSON& json, bool is_reload) { this->ip_stack_debug = json.get_bool("IPStackDebug", this->ip_stack_debug); this->allow_unregistered_users = json.get_bool("AllowUnregisteredUsers", this->allow_unregistered_users); - this->allowed_drop_modes_v1_v2 = json.get_int("AllowedDropModesV1V2", this->allowed_drop_modes_v1_v2); - this->allowed_drop_modes_v3 = json.get_int("AllowedDropModesV3", this->allowed_drop_modes_v3); - this->allowed_drop_modes_v4 = json.get_int("AllowedDropModesV4", this->allowed_drop_modes_v4); - this->default_drop_mode_v1_v2 = json.get_enum("DefaultDropModeV1V2", this->default_drop_mode_v1_v2); - this->default_drop_mode_v3 = json.get_enum("DefaultDropModeV3", this->default_drop_mode_v3); - this->default_drop_mode_v4 = json.get_enum("DefaultDropModeV4", this->default_drop_mode_v4); - if (this->default_drop_mode_v4 == Lobby::DropMode::CLIENT) { + this->allowed_drop_modes_v1_v2_normal = json.get_int("AllowedDropModesV1V2Normal", this->allowed_drop_modes_v1_v2_normal); + this->allowed_drop_modes_v1_v2_battle = json.get_int("AllowedDropModesV1V2Battle", this->allowed_drop_modes_v1_v2_battle); + this->allowed_drop_modes_v1_v2_challenge = json.get_int("AllowedDropModesV1V2Challenge", this->allowed_drop_modes_v1_v2_challenge); + this->allowed_drop_modes_v3_normal = json.get_int("AllowedDropModesV3Normal", this->allowed_drop_modes_v3_normal); + this->allowed_drop_modes_v3_battle = json.get_int("AllowedDropModesV3Battle", this->allowed_drop_modes_v3_battle); + this->allowed_drop_modes_v3_challenge = json.get_int("AllowedDropModesV3Challenge", this->allowed_drop_modes_v3_challenge); + this->allowed_drop_modes_v4_normal = json.get_int("AllowedDropModesV4Normal", this->allowed_drop_modes_v4_normal); + this->allowed_drop_modes_v4_battle = json.get_int("AllowedDropModesV4Battle", this->allowed_drop_modes_v4_battle); + this->allowed_drop_modes_v4_challenge = json.get_int("AllowedDropModesV4Challenge", this->allowed_drop_modes_v4_challenge); + this->default_drop_mode_v1_v2_normal = json.get_enum("DefaultDropModeV1V2Normal", this->default_drop_mode_v1_v2_normal); + this->default_drop_mode_v1_v2_battle = json.get_enum("DefaultDropModeV1V2Battle", this->default_drop_mode_v1_v2_battle); + this->default_drop_mode_v1_v2_challenge = json.get_enum("DefaultDropModeV1V2Challenge", this->default_drop_mode_v1_v2_challenge); + this->default_drop_mode_v3_normal = json.get_enum("DefaultDropModeV3Normal", this->default_drop_mode_v3_normal); + this->default_drop_mode_v3_battle = json.get_enum("DefaultDropModeV3Battle", this->default_drop_mode_v3_battle); + this->default_drop_mode_v3_challenge = json.get_enum("DefaultDropModeV3Challenge", this->default_drop_mode_v3_challenge); + this->default_drop_mode_v4_normal = json.get_enum("DefaultDropModeV4Normal", this->default_drop_mode_v4_normal); + this->default_drop_mode_v4_battle = json.get_enum("DefaultDropModeV4Battle", this->default_drop_mode_v4_battle); + this->default_drop_mode_v4_challenge = json.get_enum("DefaultDropModeV4Challenge", this->default_drop_mode_v4_challenge); + if ((this->default_drop_mode_v4_normal == Lobby::DropMode::CLIENT) || + (this->default_drop_mode_v4_battle == Lobby::DropMode::CLIENT) || + (this->default_drop_mode_v4_challenge == Lobby::DropMode::CLIENT)) { throw runtime_error("default V4 drop mode cannot be CLIENT"); } - if (this->allowed_drop_modes_v4 & (1 << static_cast(Lobby::DropMode::CLIENT))) { + if ((this->allowed_drop_modes_v4_normal & (1 << static_cast(Lobby::DropMode::CLIENT))) || + (this->allowed_drop_modes_v4_battle & (1 << static_cast(Lobby::DropMode::CLIENT))) || (this->allowed_drop_modes_v4_challenge & (1 << static_cast(Lobby::DropMode::CLIENT)))) { throw runtime_error("CLIENT drop mode cannot be allowed in V4"); } this->persistent_game_idle_timeout_usecs = json.get_int("PersistentGameIdleTimeout", this->persistent_game_idle_timeout_usecs); diff --git a/src/ServerState.hh b/src/ServerState.hh index 9dd12330..38177e8a 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -75,12 +75,24 @@ struct ServerState : public std::enable_shared_from_this { bool allow_unregistered_users; bool allow_dc_pc_games; bool allow_gc_xb_games; - uint8_t allowed_drop_modes_v1_v2; - uint8_t allowed_drop_modes_v3; - uint8_t allowed_drop_modes_v4; - Lobby::DropMode default_drop_mode_v1_v2; - Lobby::DropMode default_drop_mode_v3; - Lobby::DropMode default_drop_mode_v4; + uint8_t allowed_drop_modes_v1_v2_normal; + uint8_t allowed_drop_modes_v1_v2_battle; + uint8_t allowed_drop_modes_v1_v2_challenge; + uint8_t allowed_drop_modes_v3_normal; + uint8_t allowed_drop_modes_v3_battle; + uint8_t allowed_drop_modes_v3_challenge; + uint8_t allowed_drop_modes_v4_normal; + uint8_t allowed_drop_modes_v4_battle; + uint8_t allowed_drop_modes_v4_challenge; + Lobby::DropMode default_drop_mode_v1_v2_normal; + Lobby::DropMode default_drop_mode_v1_v2_battle; + Lobby::DropMode default_drop_mode_v1_v2_challenge; + Lobby::DropMode default_drop_mode_v3_normal; + Lobby::DropMode default_drop_mode_v3_battle; + Lobby::DropMode default_drop_mode_v3_challenge; + Lobby::DropMode default_drop_mode_v4_normal; + Lobby::DropMode default_drop_mode_v4_battle; + Lobby::DropMode default_drop_mode_v4_challenge; uint64_t persistent_game_idle_timeout_usecs; bool ep3_send_function_call_enabled; bool catch_handler_exceptions; diff --git a/system/config.example.json b/system/config.example.json index 65398db5..85f55106 100644 --- a/system/config.example.json +++ b/system/config.example.json @@ -721,12 +721,24 @@ // SERVER_PRIVATE = 0x08 // SERVER_DUPLICATE = 0x10 // See README.md for more information on drop modes and item tables. - "AllowedDropModesV1V2": 0x1F, // DCv1, DCv2, and PCv2 - "AllowedDropModesV3": 0x1F, // GC and Xbox - "AllowedDropModesV4": 0x1D, // BB; CLIENT not allowed - "DefaultDropModeV1V2": "CLIENT", // DCv1, DCv2, and PCv2 - "DefaultDropModeV3": "CLIENT", // GC and Xbox - "DefaultDropModeV4": "SERVER_SHARED", // BB + "AllowedDropModesV1V2Normal": 0x1F, // All modes + "AllowedDropModesV1V2Battle": 0x07, // SERVER_PRIVATE and SERVER_DUPLICATE not allowed + "AllowedDropModesV1V2Challenge": 0x07, // SERVER_PRIVATE and SERVER_DUPLICATE not allowed + "AllowedDropModesV3Normal": 0x1F, // All modes allowed + "AllowedDropModesV3Battle": 0x07, // SERVER_PRIVATE and SERVER_DUPLICATE not allowed + "AllowedDropModesV3Challenge": 0x07, // SERVER_PRIVATE and SERVER_DUPLICATE not allowed + "AllowedDropModesV4Normal": 0x1D, // CLIENT not allowed + "AllowedDropModesV4Challenge": 0x05, // CLIENT, SERVER_PRIVATE, and SERVER_DUPLICATE not allowed + "AllowedDropModesV4Battle": 0x05, // CLIENT, SERVER_PRIVATE, and SERVER_DUPLICATE not allowed + "DefaultDropModeV1V2Normal": "CLIENT", + "DefaultDropModeV1V2Battle": "CLIENT", + "DefaultDropModeV1V2Challenge": "CLIENT", + "DefaultDropModeV3Normal": "CLIENT", + "DefaultDropModeV3Battle": "CLIENT", + "DefaultDropModeV3Challenge": "CLIENT", + "DefaultDropModeV4Normal": "SERVER_SHARED", + "DefaultDropModeV4Battle": "SERVER_SHARED", + "DefaultDropModeV4Challenge": "SERVER_SHARED", // Rare enemy rates for BB games. The default rates specified here match the // original rates on the official servers. There is a hard limit of 16 rare diff --git a/tests/config.json b/tests/config.json index 3bfb173c..3f61b1bb 100644 --- a/tests/config.json +++ b/tests/config.json @@ -11,12 +11,25 @@ "CatchHandlerExceptions": false, "PersistentGameIdleTimeout": 1800000000, - "AllowedDropModesV1V2": 0x1F, - "AllowedDropModesV3": 0x1F, - "AllowedDropModesV4": 0x1D, - "DefaultDropModeV1V2": "CLIENT", - "DefaultDropModeV3": "CLIENT", - "DefaultDropModeV4": "SERVER_SHARED", + "AllowedDropModesV1V2Normal": 0x1F, + "AllowedDropModesV1V2Battle": 0x07, + "AllowedDropModesV1V2Challenge": 0x07, + "AllowedDropModesV3Normal": 0x1F, + "AllowedDropModesV3Battle": 0x07, + "AllowedDropModesV3Challenge": 0x07, + "AllowedDropModesV4Normal": 0x1D, + "AllowedDropModesV4Challenge": 0x05, + "AllowedDropModesV4Battle": 0x05, + "DefaultDropModeV1V2Normal": "CLIENT", + "DefaultDropModeV1V2Battle": "CLIENT", + "DefaultDropModeV1V2Challenge": "CLIENT", + "DefaultDropModeV3Normal": "CLIENT", + "DefaultDropModeV3Battle": "CLIENT", + "DefaultDropModeV3Challenge": "CLIENT", + "DefaultDropModeV4Normal": "SERVER_SHARED", + "DefaultDropModeV4Battle": "SERVER_SHARED", + "DefaultDropModeV4Challenge": "SERVER_SHARED", + "LocalAddress": "en0", "ExternalAddress": "en0",