diff --git a/src/c_cmds.cpp b/src/c_cmds.cpp index efc11a3d2..842516ba3 100644 --- a/src/c_cmds.cpp +++ b/src/c_cmds.cpp @@ -681,7 +681,7 @@ UNSAFE_CCMD (crashout) #endif -CCMD (dir) +UNSAFE_CCMD (dir) { FString dir, path; char curdir[256]; diff --git a/src/c_cvars.cpp b/src/c_cvars.cpp index d51dacdcb..7edf126ab 100644 --- a/src/c_cvars.cpp +++ b/src/c_cvars.cpp @@ -53,6 +53,7 @@ #include "colormatcher.h" #include "menu/menu.h" #include "vm.h" +#include "v_text.h" struct FLatchedValue { @@ -1706,6 +1707,16 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter) EXTERN_CVAR(Bool, sv_cheats); +static bool IsUnsafe(const FBaseCVar *const var) +{ + const bool unsafe = UnsafeExecutionContext && !(var->GetFlags() & CVAR_MOD); + if (unsafe) + { + Printf(TEXTCOLOR_RED "Cannot set console variable" TEXTCOLOR_GOLD " %s " TEXTCOLOR_RED "from unsafe command\n", var->GetName()); + } + return unsafe; +} + void FBaseCVar::CmdSet (const char *newval) { if ((GetFlags() & CVAR_CHEAT) && !sv_cheats) @@ -1713,6 +1724,10 @@ void FBaseCVar::CmdSet (const char *newval) Printf("sv_cheats must be true to set this console variable.\n"); return; } + else if (IsUnsafe(this)) + { + return; + } UCVarValue val; @@ -1799,6 +1814,11 @@ CCMD (toggle) { if ( (var = FindCVar (argv[1], &prev)) ) { + if (IsUnsafe(var)) + { + return; + } + val = var->GetGenericRep (CVAR_Bool); val.Bool = !val.Bool; var->SetGenericRep (val, CVAR_Bool); diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index ec4571b53..cb1fb47e1 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -127,8 +127,24 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp, Button_AM_ZoomIn, Button_AM_ZoomOut; -bool ParsingKeyConf; -static bool UnsafeExecutionContext; +bool ParsingKeyConf, UnsafeExecutionContext; + +class UnsafeExecutionScope +{ + const bool wasEnabled; + +public: + explicit UnsafeExecutionScope(const bool enable = true) + : wasEnabled(UnsafeExecutionContext) + { + UnsafeExecutionContext = enable; + } + + ~UnsafeExecutionScope() + { + UnsafeExecutionContext = wasEnabled; + } +}; // To add new actions, go to the console and type "key ". // This will give you the key value to use in the first column. Then @@ -227,10 +243,8 @@ void DWaitingCommand::Tick () { if (--TicsLeft == 0) { - const bool wasUnsafe = UnsafeExecutionContext; - UnsafeExecutionContext = IsUnsafe; + UnsafeExecutionScope scope; AddCommandString (Command); - UnsafeExecutionContext = wasUnsafe; Destroy (); } } @@ -658,12 +672,6 @@ void C_DoCommand (const char *cmd, int keynum) if (args.argc() >= 2) { // Set the variable - if (UnsafeExecutionContext && !(var->GetFlags() & CVAR_MOD)) - { - Printf(TEXTCOLOR_RED "Cannot set console variable" TEXTCOLOR_GOLD " %s " TEXTCOLOR_RED "from unsafe command\n", var->GetName()); - return; - } - var->CmdSet (args[1]); } else @@ -684,9 +692,9 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand) if (CurrentMenu == nullptr) return 0; PARAM_PROLOGUE; PARAM_STRING(cmd); - UnsafeExecutionContext = true; + PARAM_BOOL(unsafe); + UnsafeExecutionScope scope(unsafe); C_DoCommand(cmd); - UnsafeExecutionContext = false; return 0; } @@ -1515,9 +1523,8 @@ void FConsoleAlias::SafeDelete () void FUnsafeConsoleAlias::Run (FCommandLine &args, APlayerPawn *instigator, int key) { - UnsafeExecutionContext = true; + UnsafeExecutionScope scope; FConsoleAlias::Run(args, instigator, key); - UnsafeExecutionContext = false; } void FExecList::AddCommand(const char *cmd, const char *file) diff --git a/src/c_dispatch.h b/src/c_dispatch.h index dac14b818..aa82e20ba 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -200,7 +200,7 @@ extern FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, Button_User1, Button_User2, Button_User3, Button_User4, Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp, Button_AM_ZoomIn, Button_AM_ZoomOut; -extern bool ParsingKeyConf; +extern bool ParsingKeyConf, UnsafeExecutionContext; void ResetButtonTriggers (); // Call ResetTriggers for all buttons void ResetButtonStates (); // Same as above, but also clear bDown diff --git a/src/g_game.cpp b/src/g_game.cpp index 0e44e8301..d0cf74be7 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2599,7 +2599,7 @@ void G_DeferedPlayDemo (const char *name) gameaction = (gameaction == ga_loadgame) ? ga_loadgameplaydemo : ga_playdemo; } -CCMD (playdemo) +UNSAFE_CCMD (playdemo) { if (netgame) { diff --git a/src/g_inventory/a_weapons.cpp b/src/g_inventory/a_weapons.cpp index 440c67f9b..ede528338 100644 --- a/src/g_inventory/a_weapons.cpp +++ b/src/g_inventory/a_weapons.cpp @@ -220,7 +220,21 @@ void AWeapon::MarkPrecacheSounds() const // //=========================================================================== -bool AWeapon::CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo, int ammocount) +bool AWeapon::CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo, int ammocount) +{ + IFVIRTUAL(AWeapon, CheckAmmo) + { + VMValue params[] = { (DObject*)this, fireMode, autoSwitch, requireAmmo, ammocount }; + VMReturn ret; + int retval; + ret.IntAt(&retval); + VMCall(func, params, 5, &ret, 1); + return !!retval; + } + return CheckAmmo(fireMode, autoSwitch, requireAmmo, ammocount); +} + +bool AWeapon::DoCheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo, int ammocount) { int altFire; int count1, count2; @@ -293,7 +307,7 @@ DEFINE_ACTION_FUNCTION(AWeapon, CheckAmmo) PARAM_BOOL(autoswitch); PARAM_BOOL_DEF(require); PARAM_INT_DEF(ammocnt); - ACTION_RETURN_BOOL(self->CheckAmmo(mode, autoswitch, require, ammocnt)); + ACTION_RETURN_BOOL(self->DoCheckAmmo(mode, autoswitch, require, ammocnt)); } //=========================================================================== @@ -306,7 +320,21 @@ DEFINE_ACTION_FUNCTION(AWeapon, CheckAmmo) // //=========================================================================== -bool AWeapon::DepleteAmmo (bool altFire, bool checkEnough, int ammouse) +bool AWeapon::DepleteAmmo(bool altFire, bool checkEnough, int ammouse) +{ + IFVIRTUAL(AWeapon, DepleteAmmo) + { + VMValue params[] = { (DObject*)this, AltFire, checkEnough, ammouse }; + VMReturn ret; + int retval; + ret.IntAt(&retval); + VMCall(func, params, 4, &ret, 1); + return !!retval; + } + return DoDepleteAmmo(altFire, checkEnough, ammouse); +} + +bool AWeapon::DoDepleteAmmo (bool altFire, bool checkEnough, int ammouse) { if (!((dmflags & DF_INFINITE_AMMO) || (Owner->FindInventory (PClass::FindActor(NAME_PowerInfiniteAmmo), true) != nullptr))) { @@ -357,7 +385,7 @@ DEFINE_ACTION_FUNCTION(AWeapon, DepleteAmmo) PARAM_BOOL(altfire); PARAM_BOOL_DEF(checkenough); PARAM_INT_DEF(ammouse); - ACTION_RETURN_BOOL(self->DepleteAmmo(altfire, checkenough, ammouse)); + ACTION_RETURN_BOOL(self->DoDepleteAmmo(altfire, checkenough, ammouse)); } diff --git a/src/g_inventory/a_weapons.h b/src/g_inventory/a_weapons.h index 9b397e402..4c6f6ab45 100644 --- a/src/g_inventory/a_weapons.h +++ b/src/g_inventory/a_weapons.h @@ -142,7 +142,9 @@ public: EitherFire }; bool CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo=false, int ammocount = -1); + bool DoCheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo, int ammocount); bool DepleteAmmo (bool altFire, bool checkEnough=true, int ammouse = -1); + bool DoDepleteAmmo(bool altFire, bool checkEnough, int ammouse); enum { diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index ac7eccac3..a1816acd2 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -987,9 +987,8 @@ void GLSprite::Process(AActor* thing, sector_t * sector, int thruportal) RenderStyle.CheckFuzz(); if (RenderStyle.BlendOp == STYLEOP_Fuzz) { - if (gl_fuzztype != 0 && !gl.legacyMode) + if (gl_fuzztype != 0 && !gl.legacyMode && !(RenderStyle.Flags & STYLEF_InvertSource)) { - // Todo: implement shader selection here RenderStyle = LegacyRenderStyles[STYLE_Translucent]; OverrideShader = SHADER_NoTexture + gl_fuzztype; trans = 0.99f; // trans may not be 1 here diff --git a/src/m_misc.cpp b/src/m_misc.cpp index eb51ec7b9..481f956b5 100644 --- a/src/m_misc.cpp +++ b/src/m_misc.cpp @@ -673,7 +673,7 @@ void M_ScreenShot (const char *filename) } } -CCMD (screenshot) +UNSAFE_CCMD (screenshot) { if (argv.argc() == 1) G_ScreenShot (NULL); diff --git a/src/menu/menu.cpp b/src/menu/menu.cpp index 86ec78abf..f03c37eb7 100644 --- a/src/menu/menu.cpp +++ b/src/menu/menu.cpp @@ -58,6 +58,7 @@ #include "vm.h" #include "events.h" #include "gl/renderer/gl_renderer.h" // for menu blur +#include "scripting/types.h" // // Todo: Move these elsewhere @@ -1180,6 +1181,8 @@ DMenuItemBase * CreateOptionMenuItemCommand(const char *label, FName cmd, bool c VMValue params[] = { p, &namestr, cmd.GetIndex(), centered }; auto f = dyn_cast(c->FindSymbol("Init", false)); VMCall(f->Variants[0].Implementation, params, countof(params), nullptr, 0); + auto unsafe = dyn_cast(c->FindSymbol("mUnsafe", false)); + unsafe->Type->SetValue(reinterpret_cast(p) + unsafe->Offset, 0); return (DMenuItemBase*)p; } diff --git a/src/p_glnodes.cpp b/src/p_glnodes.cpp index bd574ad83..60c666e82 100644 --- a/src/p_glnodes.cpp +++ b/src/p_glnodes.cpp @@ -1216,7 +1216,7 @@ errorout: return false; } -CCMD(clearnodecache) +UNSAFE_CCMD(clearnodecache) { TArray list; FString path = M_GetCachePath(false); diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 24c30375e..6b19942e0 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -809,11 +809,13 @@ bool FMultiBlockLinesIterator::GoUp(double x, double y) { if (!cursector->PortalBlocksMovement(sector_t::ceiling)) { - startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling)); - portalflags = FFCF_NOFLOOR; - return true; + if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::ceiling))) + { + portalflags = FFCF_NOFLOOR; + return true; + } } - else continueup = false; + continueup = false; } return false; } @@ -830,11 +832,13 @@ bool FMultiBlockLinesIterator::GoDown(double x, double y) { if (!cursector->PortalBlocksMovement(sector_t::floor)) { - startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor)); - portalflags = FFCF_NOCEILING; - return true; + if (startIteratorForGroup(cursector->GetOppositePortalGroup(sector_t::floor))) + { + portalflags = FFCF_NOCEILING; + return true; + } } - else continuedown = false; + continuedown = false; } return false; } @@ -906,14 +910,19 @@ bool FMultiBlockLinesIterator::Next(FMultiBlockLinesIterator::CheckResult *item) // //=========================================================================== -void FMultiBlockLinesIterator::startIteratorForGroup(int group) +bool FMultiBlockLinesIterator::startIteratorForGroup(int group) { offset = Displacements.getOffset(basegroup, group); offset.X += checkpoint.X; offset.Y += checkpoint.Y; cursector = group == startsector->PortalGroup ? startsector : P_PointInSector(offset); + // If we ended up in a different group, + // presumably because the spot to be checked is too far outside the actual portal group, + // the search needs to abort. + if (cursector->PortalGroup != group) return false; bbox.setBox(offset.X, offset.Y, checkpoint.Z); blockIterator.init(bbox); + return true; } //=========================================================================== diff --git a/src/p_maputl.h b/src/p_maputl.h index 8ac3ea76a..4dfa99e0f 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -240,7 +240,7 @@ class FMultiBlockLinesIterator bool GoUp(double x, double y); bool GoDown(double x, double y); - void startIteratorForGroup(int group); + bool startIteratorForGroup(int group); public: diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 79f549dd3..e0c9530d3 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -7766,7 +7766,13 @@ FState *AActor::GetRaiseState() void AActor::Revive() { AActor *info = GetDefault(); + FLinkContext ctx; + + bool flagchange = (flags & (MF_NOBLOCKMAP | MF_NOSECTOR)) != (info->flags & (MF_NOBLOCKMAP | MF_NOSECTOR)); + + if (flagchange) UnlinkFromWorld(&ctx); flags = info->flags; + if (flagchange) LinkToWorld(&ctx); flags2 = info->flags2; flags3 = info->flags3; flags4 = info->flags4; diff --git a/src/s_sound.cpp b/src/s_sound.cpp index fede842b1..d3f587b94 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -2999,7 +2999,7 @@ CCMD (cd_resume) // //========================================================================== -CCMD (playlist) +UNSAFE_CCMD (playlist) { int argc = argv.argc(); diff --git a/src/sound/mididevices/music_fluidsynth_mididevice.cpp b/src/sound/mididevices/music_fluidsynth_mididevice.cpp index 07102c43d..42244b61a 100644 --- a/src/sound/mididevices/music_fluidsynth_mididevice.cpp +++ b/src/sound/mididevices/music_fluidsynth_mididevice.cpp @@ -124,13 +124,13 @@ CUSTOM_CVAR(Float, fluid_gain, 0.5, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) currSong->FluidSettingNum("synth.gain", self); } -CUSTOM_CVAR(Bool, fluid_reverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Bool, fluid_reverb, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (currSong != NULL) currSong->FluidSettingInt("synth.reverb.active", self); } -CUSTOM_CVAR(Bool, fluid_chorus, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CUSTOM_CVAR(Bool, fluid_chorus, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (currSong != NULL) currSong->FluidSettingInt("synth.chorus.active", self); diff --git a/wadsrc/static/zscript/inventory/weapons.txt b/wadsrc/static/zscript/inventory/weapons.txt index f837bf4e5..4786e44d7 100644 --- a/wadsrc/static/zscript/inventory/weapons.txt +++ b/wadsrc/static/zscript/inventory/weapons.txt @@ -78,8 +78,8 @@ class Weapon : StateProvider native Stop; } - native bool CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo = false, int ammocount = -1); - native bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1); + native virtual bool CheckAmmo(int fireMode, bool autoSwitch, bool requireAmmo = false, int ammocount = -1); + native virtual bool DepleteAmmo(bool altFire, bool checkEnough = true, int ammouse = -1); virtual State GetReadyState () { diff --git a/wadsrc/static/zscript/menu/optionmenuitems.txt b/wadsrc/static/zscript/menu/optionmenuitems.txt index 4668ea068..00fe4893c 100644 --- a/wadsrc/static/zscript/menu/optionmenuitems.txt +++ b/wadsrc/static/zscript/menu/optionmenuitems.txt @@ -128,16 +128,18 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu { private String ccmd; // do not allow access to this from the outside. bool mCloseOnSelect; + private bool mUnsafe; OptionMenuItemCommand Init(String label, Name command, bool centered = false, bool closeonselect = false) { Super.Init(label, command, 0, centered); ccmd = command; mCloseOnSelect = closeonselect; + mUnsafe = true; return self; } - private native static void DoCommand(String cmd); // This is very intentionally limited to this menu item to prevent abuse. + private native static void DoCommand(String cmd, bool unsafe); // This is very intentionally limited to this menu item to prevent abuse. override bool Activate() { @@ -151,7 +153,7 @@ class OptionMenuItemCommand : OptionMenuItemSubmenu if (m.GetItem(mAction) != self) return false; } Menu.MenuSound("menu/choose"); - DoCommand(ccmd); + DoCommand(ccmd, mUnsafe); if (mCloseOnSelect) { let curmenu = Menu.GetCurrentMenu();