Merge pull request #11476 from Jamiras/cheevos_core_options_blacklist

(cheevos) core options blacklist
This commit is contained in:
Autechre 2020-10-23 02:43:05 +02:00 committed by GitHub
commit 6b3789513f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 203 additions and 26 deletions

View File

@ -65,6 +65,7 @@
#include "../msg_hash.h"
#include "../retroarch.h"
#include "../core.h"
#include "../core_option_manager.h"
#include "../version.h"
#include "../frontend/frontend_driver.h"
@ -1429,6 +1430,11 @@ static void rcheevos_toggle_hardcore_active(rcheevos_locals_t* locals)
/* activate hardcore */
locals->hardcore_active = true;
/* if one or more invalid settings is enabled, abort*/
rcheevos_validate_config_settings();
if (!locals->hardcore_active)
return;
if (locals->loaded)
{
const char* msg = msg_hash_to_str(MSG_CHEEVOS_HARDCORE_MODE_ENABLE);
@ -1500,6 +1506,175 @@ void rcheevos_hardcore_enabled_changed(void)
}
}
typedef struct rc_disallowed_setting_t
{
const char* setting;
const char* value;
} rc_disallowed_setting_t;
typedef struct rc_disallowed_core_settings_t
{
const char* library_name;
const rc_disallowed_setting_t* disallowed_settings;
} rc_disallowed_core_settings_t;
static const rc_disallowed_setting_t _rc_disallowed_dolphin_settings[] = {
{ "dolphin_cheats_enabled", "enabled" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_ecwolf_settings[] = {
{ "ecwolf-invulnerability", "enabled" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_fbneo_settings[] = {
{ "fbneo-allow-patched-romsets", "enabled" },
{ "fbneo-cheat-*", "!,Disabled,0 - Disabled" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_gpgx_settings[] = {
{ "genesis_plus_gx_lock_on", ",action replay (pro),game genie" },
{ NULL, NULL }
};
static const rc_disallowed_setting_t _rc_disallowed_ppsspp_settings[] = {
{ "ppsspp_cheats", "enabled" },
{ NULL, NULL }
};
static const rc_disallowed_core_settings_t rc_disallowed_core_settings[] = {
{ "dolphin-emu", _rc_disallowed_dolphin_settings },
{ "ecwolf", _rc_disallowed_ecwolf_settings },
{ "FinalBurn Neo", _rc_disallowed_fbneo_settings },
{ "Genesis Plus GX", _rc_disallowed_gpgx_settings },
{ "PPSSPP", _rc_disallowed_ppsspp_settings },
{ NULL, NULL }
};
static int rcheevos_match_value(const char* val, const char* match)
{
/* if value starts with a comma, it's a CSV list of potential matches */
if (*match == ',')
{
do
{
const char* ptr = ++match;
int size;
while (*match && *match != ',')
++match;
size = match - ptr;
if (val[size] == '\0')
{
if (string_is_equal_fast(ptr, val, size))
{
return true;
}
else
{
char buffer[128];
memcpy(buffer, ptr, size);
buffer[size] = '\0';
if (string_is_equal_case_insensitive(buffer, val))
return true;
}
}
} while (*match == ',');
return false;
}
/* a leading exclamation point means the provided value(s) are not forbidden (are allowed) */
if (*match == '!')
return !rcheevos_match_value(val, &match[1]);
/* just a single value, attempt to match it */
return string_is_equal_case_insensitive(val, match);
}
void rcheevos_validate_config_settings(void)
{
const rc_disallowed_core_settings_t* core_filter = rc_disallowed_core_settings;
struct retro_system_info* system = runloop_get_libretro_system_info();
if (!system->library_name || !rcheevos_hardcore_active())
return;
while (core_filter->library_name)
{
if (string_is_equal(core_filter->library_name, system->library_name))
{
core_option_manager_t* coreopts = NULL;
if (rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts))
{
const rc_disallowed_setting_t* disallowed_setting = core_filter->disallowed_settings;
const char* key;
const char* val;
int i;
int allowed = 1;
size_t key_len;
for (; disallowed_setting->setting; ++disallowed_setting)
{
key = disallowed_setting->setting;
key_len = strlen(key);
if (key[key_len - 1] == '*')
{
for (i = 0; i < coreopts->size; i++)
{
if (string_starts_with_size(coreopts->opts[i].key, key, key_len - 1))
{
val = core_option_manager_get_val(coreopts, i);
if (rcheevos_match_value(val, disallowed_setting->value))
{
key = coreopts->opts[i].key;
allowed = 0;
break;
}
}
}
}
else
{
for (i = 0; i < coreopts->size; i++)
{
if (string_is_equal(coreopts->opts[i].key, key))
{
val = core_option_manager_get_val(coreopts, i);
if (rcheevos_match_value(val, disallowed_setting->value))
{
allowed = 0;
break;
}
}
}
}
if (!allowed)
{
char buffer[256];
snprintf(buffer, sizeof(buffer), "Hardcore paused. Setting not allowed: %s=%s", key, val);
CHEEVOS_LOG(RCHEEVOS_TAG "%s\n", buffer);
rcheevos_pause_hardcore();
runloop_msg_queue_push(buffer, 0, 4 * 60, false, NULL,
MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_WARNING);
break;
}
}
}
break;
}
++core_filter;
}
}
static void rcheevos_runtime_event_handler(const rc_runtime_event_t* runtime_event)
{
switch (runtime_event->type)
@ -2417,6 +2592,7 @@ bool rcheevos_load(const void *data)
/* reset hardcore mode and leaderboard settings based on configs */
rcheevos_hardcore_enabled_changed();
rcheevos_validate_config_settings();
rcheevos_leaderboards_enabled_changed();
coro = (rcheevos_coro_t*)calloc(1, sizeof(*coro));

View File

@ -57,6 +57,8 @@ bool rcheevos_unload(void);
void rcheevos_hardcore_enabled_changed(void);
void rcheevos_toggle_hardcore_paused(void);
void rcheevos_validate_config_settings(void);
void rcheevos_leaderboards_enabled_changed(void);
void rcheevos_test(void);

View File

@ -18526,7 +18526,7 @@ bool core_option_manager_get_visible(core_option_manager_t *opt,
void core_option_manager_set_val(core_option_manager_t *opt,
size_t idx, size_t val_idx)
{
struct core_option *option= NULL;
struct core_option *option = NULL;
if (!opt)
return;
@ -18537,6 +18537,24 @@ void core_option_manager_set_val(core_option_manager_t *opt,
option->index = val_idx % option->vals->size;
opt->updated = true;
rcheevos_validate_config_settings();
}
static void core_option_manager_adjust_val(core_option_manager_t* opt,
size_t idx, int adjustment)
{
struct core_option* option = NULL;
if (!opt)
return;
if (idx >= opt->size)
return;
option = (struct core_option*)&opt->opts[idx];
option->index = (option->index + option->vals->size + adjustment) % option->vals->size;
opt->updated = true;
rcheevos_validate_config_settings();
}
/**
@ -18555,6 +18573,8 @@ void core_option_manager_set_default(core_option_manager_t *opt, size_t idx)
opt->opts[idx].index = opt->opts[idx].default_index;
opt->updated = true;
rcheevos_validate_config_settings();
}
static struct retro_core_option_definition *core_option_manager_get_definitions(
@ -38200,20 +38220,10 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data)
* Options wrap around.
*/
{
struct core_option *option = NULL;
unsigned *idx = (unsigned*)data;
unsigned *idx = (unsigned*)data;
if (!idx || !p_rarch->runloop_core_options)
return false;
option = (struct core_option*)
&p_rarch->runloop_core_options->opts[*idx];
if (option)
{
option->index =
(option->index + option->vals->size - 1) %
option->vals->size;
p_rarch->runloop_core_options->updated = true;
}
core_option_manager_adjust_val(p_rarch->runloop_core_options, *idx, -1);
}
break;
case RARCH_CTL_CORE_OPTION_NEXT:
@ -38222,21 +38232,10 @@ bool rarch_ctl(enum rarch_ctl_state state, void *data)
* Options wrap around.
*/
{
struct core_option *option = NULL;
unsigned *idx = (unsigned*)data;
unsigned* idx = (unsigned*)data;
if (!idx || !p_rarch->runloop_core_options)
return false;
option =
(struct core_option*)&p_rarch->runloop_core_options->opts[*idx];
if (option)
{
option->index =
(option->index + 1) % option->vals->size;
p_rarch->runloop_core_options->updated = true;
}
core_option_manager_adjust_val(p_rarch->runloop_core_options, *idx, 1);
}
break;