- be more thorough with 'in menu' checks for certain protected functions.

They would also pass the test if a menu just was open but not the actual invoker.
Also error out if this happens so that modders can see that they are doing unsupported things. Silent failure is not a good idea here.
This commit is contained in:
Christoph Oelckers 2018-09-15 12:30:05 +02:00
parent 53ee7cfc7b
commit 3046a7dd81
4 changed files with 48 additions and 4 deletions

View File

@ -45,6 +45,7 @@
#include "dobject.h"
#include "vm.h"
#include "i_time.h"
#include "menu/menu.h"
const char *KeyNames[NUM_KEYS] =
{
@ -267,6 +268,14 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind)
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
PARAM_INT(k);
PARAM_STRING(cmd);
// Only menus are allowed to change bindings.
if (DMenu::InMenu == 0)
{
I_FatalError("Attempt to change key bindings outside of menu code to '%s'", cmd.GetChars());
}
self->SetBind(k, cmd);
return 0;
}
@ -506,6 +515,13 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand)
{
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
PARAM_STRING(cmd);
// Only menus are allowed to change bindings.
if (DMenu::InMenu == 0)
{
I_FatalError("Attempt to unbind key bindings for '%s' outside of menu code", cmd.GetChars());
}
self->UnbindACommand(cmd);
return 0;
}

View File

@ -220,7 +220,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
{
// Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0;
if (!(self->GetFlags() & CVAR_MOD))
{
// Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0)
{
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName());
}
}
PARAM_INT(val);
UCVarValue v;
v.Int = val;
@ -230,9 +237,15 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
DEFINE_ACTION_FUNCTION(_CVar, SetFloat)
{
// Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0;
if (!(self->GetFlags() & CVAR_MOD))
{
// Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0)
{
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName());
}
}
PARAM_FLOAT(val);
UCVarValue v;
v.Float = (float)val;
@ -244,7 +257,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString)
{
// Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar);
if (!(self->GetFlags() & CVAR_MOD) && CurrentMenu == nullptr) return 0;
if (!(self->GetFlags() & CVAR_MOD))
{
// Only menus are allowed to change non-mod CVARs.
if (DMenu::InMenu == 0)
{
I_FatalError("Attempt to change CVAR '%s' outside of menu code", self->GetName());
}
}
PARAM_STRING(val);
UCVarValue v;
v.String = val.GetChars();

View File

@ -53,6 +53,7 @@
#include "events.h"
#include "scripting/types.h"
int DMenu::InMenu;
//
// Todo: Move these elsewhere
//
@ -190,7 +191,9 @@ bool DMenu::CallResponder(event_t *ev)
VMValue params[] = { (DObject*)this, &e };
int retval;
VMReturn ret(&retval);
InMenu++;
VMCall(func, params, 2, &ret, 1);
InMenu--;
return !!retval;
}
}
@ -202,7 +205,9 @@ bool DMenu::CallResponder(event_t *ev)
VMValue params[] = { (DObject*)this, &e };
int retval;
VMReturn ret(&retval);
InMenu++;
VMCall(func, params, 2, &ret, 1);
InMenu--;
return !!retval;
}
}
@ -222,7 +227,9 @@ bool DMenu::CallMenuEvent(int mkey, bool fromcontroller)
VMValue params[] = { (DObject*)this, mkey, fromcontroller };
int retval;
VMReturn ret(&retval);
InMenu++;
VMCall(func, params, 3, &ret, 1);
InMenu--;
return !!retval;
}
else return false;

View File

@ -265,6 +265,7 @@ public:
bool mMouseCapture;
bool mBackbuttonSelected;
bool DontDim;
static int InMenu;
DMenu(DMenu *parent = NULL);
bool TranslateKeyboardEvents();