- 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 "dobject.h"
#include "vm.h" #include "vm.h"
#include "i_time.h" #include "i_time.h"
#include "menu/menu.h"
const char *KeyNames[NUM_KEYS] = const char *KeyNames[NUM_KEYS] =
{ {
@ -267,6 +268,14 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, SetBind)
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
PARAM_INT(k); PARAM_INT(k);
PARAM_STRING(cmd); 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); self->SetBind(k, cmd);
return 0; return 0;
} }
@ -506,6 +515,13 @@ DEFINE_ACTION_FUNCTION(FKeyBindings, UnbindACommand)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings); PARAM_SELF_STRUCT_PROLOGUE(FKeyBindings);
PARAM_STRING(cmd); 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); self->UnbindACommand(cmd);
return 0; return 0;
} }

View file

@ -220,7 +220,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
{ {
// Only menus are allowed to change CVARs. // Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); 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); PARAM_INT(val);
UCVarValue v; UCVarValue v;
v.Int = val; v.Int = val;
@ -230,9 +237,15 @@ DEFINE_ACTION_FUNCTION(_CVar, SetInt)
DEFINE_ACTION_FUNCTION(_CVar, SetFloat) DEFINE_ACTION_FUNCTION(_CVar, SetFloat)
{ {
// Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); 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); PARAM_FLOAT(val);
UCVarValue v; UCVarValue v;
v.Float = (float)val; v.Float = (float)val;
@ -244,7 +257,14 @@ DEFINE_ACTION_FUNCTION(_CVar, SetString)
{ {
// Only menus are allowed to change CVARs. // Only menus are allowed to change CVARs.
PARAM_SELF_STRUCT_PROLOGUE(FBaseCVar); 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); PARAM_STRING(val);
UCVarValue v; UCVarValue v;
v.String = val.GetChars(); v.String = val.GetChars();

View file

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

View file

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