From 4b252b30e38b09fcb9bdf37673b3c567a3e5670c Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Wed, 30 Jan 2013 14:22:46 +0100 Subject: [PATCH] various mutator system fixes; add proper rollback of failed add, fixes #1145 --- qcsrc/server/mutators/base.qc | 10 ++++++-- qcsrc/server/mutators/base.qh | 4 +++- qcsrc/server/mutators/gamemode_ctf.qc | 10 +++++++- qcsrc/server/mutators/gamemode_freezetag.qc | 10 +++++++- qcsrc/server/mutators/gamemode_keepaway.qc | 10 +++++++- qcsrc/server/mutators/gamemode_keyhunt.qc | 10 +++++++- qcsrc/server/mutators/gamemode_nexball.qc | 13 ++++++++++ qcsrc/server/mutators/gamemode_onslaught.qc | 9 ++++++- qcsrc/server/mutators/mutator_dodging.qc | 24 +++++-------------- qcsrc/server/mutators/mutator_new_toys.qc | 12 +++++++++- qcsrc/server/mutators/mutator_nix.qc | 5 ++++ .../server/mutators/mutator_physical_items.qc | 24 +++++++++++++++---- qcsrc/server/mutators/mutator_superspec.qc | 8 ------- qcsrc/server/mutators/sandbox.qc | 10 ++++++++ 14 files changed, 119 insertions(+), 40 deletions(-) diff --git a/qcsrc/server/mutators/base.qc b/qcsrc/server/mutators/base.qc index 368ab5898..f4761b884 100644 --- a/qcsrc/server/mutators/base.qc +++ b/qcsrc/server/mutators/base.qc @@ -116,8 +116,14 @@ float Mutator_Add(mutatorfunc_t func, string name) // good return 1; } - backtrace("WARNING: when adding mutator: adding failed\n"); - Mutator_Remove(func, name); + + backtrace("WARNING: when adding mutator: adding failed, rolling back\n"); + + if(func(MUTATOR_ROLLING_BACK) != 0) + { + // baaaaad + error("WARNING: when adding mutator: rolling back failed"); + } return 0; } void Mutator_Remove(float(float) func, string name) diff --git a/qcsrc/server/mutators/base.qh b/qcsrc/server/mutators/base.qh index a422d25bc..d90d564b5 100644 --- a/qcsrc/server/mutators/base.qh +++ b/qcsrc/server/mutators/base.qh @@ -18,6 +18,7 @@ float CallbackChain_Call(entity cb); #define MUTATOR_REMOVING 0 #define MUTATOR_ADDING 1 +#define MUTATOR_ROLLING_BACK 2 typedef float(float) mutatorfunc_t; float Mutator_Add(mutatorfunc_t func, string name); void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail @@ -27,9 +28,10 @@ void Mutator_Remove(mutatorfunc_t func, string name); // calls error() on fail #define MUTATOR_DEFINITION(name) float MUTATOR_##name(float mode) #define MUTATOR_DECLARATION(name) float MUTATOR_##name(float mode) #define MUTATOR_HOOKFUNCTION(name) float HOOKFUNCTION_##name() -#define MUTATOR_HOOK(cb,func,order) do { if(mode == MUTATOR_ADDING) { if(!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); if(!CallbackChain_Add(HOOK_##cb,HOOKFUNCTION_##func,order)) { print("HOOK FAILED: ", #func, "\n"); return 1; } } else if(mode == MUTATOR_REMOVING) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0) +#define MUTATOR_HOOK(cb,func,order) do { if(mode == MUTATOR_ADDING) { if(!HOOK_##cb) HOOK_##cb = CallbackChain_New(#cb); if(!CallbackChain_Add(HOOK_##cb,HOOKFUNCTION_##func,order)) { print("HOOK FAILED: ", #func, "\n"); return 1; } } else if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) { if(HOOK_##cb) CallbackChain_Remove(HOOK_##cb,HOOKFUNCTION_##func); } } while(0) #define MUTATOR_ONADD if(mode == MUTATOR_ADDING) #define MUTATOR_ONREMOVE if(mode == MUTATOR_REMOVING) +#define MUTATOR_ONROLLBACK_OR_REMOVE if(mode == MUTATOR_REMOVING || mode == MUTATOR_ROLLING_BACK) #define MUTATOR_HOOKABLE(cb) entity HOOK_##cb #define MUTATOR_CALLHOOK(cb) CallbackChain_Call(HOOK_##cb) diff --git a/qcsrc/server/mutators/gamemode_ctf.qc b/qcsrc/server/mutators/gamemode_ctf.qc index 908d81cf3..134e979d1 100644 --- a/qcsrc/server/mutators/gamemode_ctf.qc +++ b/qcsrc/server/mutators/gamemode_ctf.qc @@ -2200,9 +2200,17 @@ MUTATOR_DEFINITION(gamemode_ctf) ctf_Initialize(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back ctf_Initialize here + // BUT: we don't need to! If this gets called, adding always + // succeeds. + } + MUTATOR_ONREMOVE { - error("This is a game type and it cannot be removed at runtime."); + print("This is a game type and it cannot be removed at runtime."); + return -1; } return 0; diff --git a/qcsrc/server/mutators/gamemode_freezetag.qc b/qcsrc/server/mutators/gamemode_freezetag.qc index aedfd6364..116eecbbf 100644 --- a/qcsrc/server/mutators/gamemode_freezetag.qc +++ b/qcsrc/server/mutators/gamemode_freezetag.qc @@ -476,9 +476,17 @@ MUTATOR_DEFINITION(gamemode_freezetag) freezetag_Initialize(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back freezetag_Initialize here + // BUT: we don't need to! If this gets called, adding always + // succeeds. + } + MUTATOR_ONREMOVE { - error("This is a game type and it cannot be removed at runtime."); + print("This is a game type and it cannot be removed at runtime."); + return -1; } return 0; diff --git a/qcsrc/server/mutators/gamemode_keepaway.qc b/qcsrc/server/mutators/gamemode_keepaway.qc index 9f8647d9d..3be0b0352 100644 --- a/qcsrc/server/mutators/gamemode_keepaway.qc +++ b/qcsrc/server/mutators/gamemode_keepaway.qc @@ -426,9 +426,17 @@ MUTATOR_DEFINITION(gamemode_keepaway) ka_Initialize(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back ka_Initialize here + // BUT: we don't need to! If this gets called, adding always + // succeeds. + } + MUTATOR_ONREMOVE { - error("This is a game type and it cannot be removed at runtime."); + print("This is a game type and it cannot be removed at runtime."); + return -1; } return 0; diff --git a/qcsrc/server/mutators/gamemode_keyhunt.qc b/qcsrc/server/mutators/gamemode_keyhunt.qc index 58d732d7f..592fa327c 100644 --- a/qcsrc/server/mutators/gamemode_keyhunt.qc +++ b/qcsrc/server/mutators/gamemode_keyhunt.qc @@ -1111,9 +1111,17 @@ MUTATOR_DEFINITION(gamemode_keyhunt) kh_Initialize(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back kh_Initialize here + // BUT: we don't need to! If this gets called, adding always + // succeeds. + } + MUTATOR_ONREMOVE { - error("This is a game type and it cannot be removed at runtime."); + print("This is a game type and it cannot be removed at runtime."); + return -1; } return 0; diff --git a/qcsrc/server/mutators/gamemode_nexball.qc b/qcsrc/server/mutators/gamemode_nexball.qc index 5f27b60a5..62cfd01ad 100644 --- a/qcsrc/server/mutators/gamemode_nexball.qc +++ b/qcsrc/server/mutators/gamemode_nexball.qc @@ -979,5 +979,18 @@ MUTATOR_DEFINITION(gamemode_nexball) InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // we actually cannot roll back nb_delayedinit here + // BUT: we don't need to! If this gets called, adding always + // succeeds. + } + + MUTATOR_ONREMOVE + { + print("This is a game type and it cannot be removed at runtime."); + return -1; + } + return 0; } diff --git a/qcsrc/server/mutators/gamemode_onslaught.qc b/qcsrc/server/mutators/gamemode_onslaught.qc index 8137cc304..dd0152ed0 100644 --- a/qcsrc/server/mutators/gamemode_onslaught.qc +++ b/qcsrc/server/mutators/gamemode_onslaught.qc @@ -1696,7 +1696,14 @@ MUTATOR_DEFINITION(gamemode_onslaught) MUTATOR_ONADD { - //InitializeEntity(world, nb_delayedinit, INITPRIO_GAMETYPE); + if(time > 1) // game loads at time 1 + error("This is a game type and it cannot be added at runtime."); + } + + MUTATOR_ONREMOVE + { + print("This is a game type and it cannot be removed at runtime."); + return -1; } return 0; diff --git a/qcsrc/server/mutators/mutator_dodging.qc b/qcsrc/server/mutators/mutator_dodging.qc index bdd39b128..5cb328c2e 100644 --- a/qcsrc/server/mutators/mutator_dodging.qc +++ b/qcsrc/server/mutators/mutator_dodging.qc @@ -27,21 +27,6 @@ // the jump part of the dodge cannot be ramped .float dodging_single_action; -void dodging_Initialize() { - // print("dodging_Initialize\n"); - - self.last_FORWARD_KEY_time = 0; - self.last_BACKWARD_KEY_time = 0; - self.last_RIGHT_KEY_time = 0; - self.last_LEFT_KEY_time = 0; - self.last_dodging_time = 0; - self.dodging_action = 0; - self.dodging_velocity_gain = 0; - self.dodging_single_action = 0; - self.dodging_direction_x = 0; - self.dodging_direction_y = 0; -} - MUTATOR_HOOKFUNCTION(dodging_GetCvars) { GetCvars_handleFloat(get_cvars_s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout"); return 0; @@ -283,14 +268,17 @@ MUTATOR_DEFINITION(mutator_dodging) MUTATOR_ONADD { g_dodging = 1; - dodging_Initialize(); } // this just turns off the cvar. - MUTATOR_ONREMOVE - { + MUTATOR_ONROLLBACK_OR_REMOVE + { g_dodging = 0; } + MUTATOR_ONREMOVE + { + } + return 0; } diff --git a/qcsrc/server/mutators/mutator_new_toys.qc b/qcsrc/server/mutators/mutator_new_toys.qc index cc4f94324..6ee3e87b3 100644 --- a/qcsrc/server/mutators/mutator_new_toys.qc +++ b/qcsrc/server/mutators/mutator_new_toys.qc @@ -208,9 +208,19 @@ MUTATOR_DEFINITION(mutator_new_toys) if(nt_IsNewToy(i)) get_weaponinfo(i).spawnflags &~= WEP_FLAG_MUTATORBLOCKED; } + + MUTATOR_ONROLLBACK_OR_REMOVE + { + float i; + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + if(nt_IsNewToy(i)) + get_weaponinfo(i).spawnflags |= WEP_FLAG_MUTATORBLOCKED; + } + MUTATOR_ONREMOVE { - error("This cannot be removed at runtime\n"); + print("This cannot be removed at runtime\n"); + return -1; } return 0; diff --git a/qcsrc/server/mutators/mutator_nix.qc b/qcsrc/server/mutators/mutator_nix.qc index dad19e4a3..b492ee60e 100644 --- a/qcsrc/server/mutators/mutator_nix.qc +++ b/qcsrc/server/mutators/mutator_nix.qc @@ -247,6 +247,11 @@ MUTATOR_DEFINITION(mutator_nix) NIX_precache(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // nothing to roll back + } + MUTATOR_ONREMOVE { // as the PlayerSpawn hook will no longer run, NIX is turned off by this! diff --git a/qcsrc/server/mutators/mutator_physical_items.qc b/qcsrc/server/mutators/mutator_physical_items.qc index 285dc4a7c..74b7db2f0 100644 --- a/qcsrc/server/mutators/mutator_physical_items.qc +++ b/qcsrc/server/mutators/mutator_physical_items.qc @@ -100,14 +100,28 @@ MUTATOR_HOOKFUNCTION(item_spawning) MUTATOR_DEFINITION(mutator_physical_items) { + MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY); + // check if we have a physics engine - if not(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) + MUTATOR_ONADD { - dprint("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n"); - return FALSE; + if not(autocvar_physics_ode && checkextension("DP_PHYSICS_ODE")) + { + dprint("Warning: Physical items are enabled but no physics engine can be used. Reverting to old items.\n"); + return -1; + } } - MUTATOR_HOOK(Item_Spawn, item_spawning, CBC_ORDER_ANY); + MUTATOR_ONROLLBACK_OR_REMOVE + { + // nothing to roll back + } - return FALSE; + MUTATOR_ONREMOVE + { + print("This cannot be removed at runtime\n"); + return -1; + } + + return 0; } diff --git a/qcsrc/server/mutators/mutator_superspec.qc b/qcsrc/server/mutators/mutator_superspec.qc index 87915f9af..0645b4805 100644 --- a/qcsrc/server/mutators/mutator_superspec.qc +++ b/qcsrc/server/mutators/mutator_superspec.qc @@ -518,13 +518,5 @@ MUTATOR_DEFINITION(mutator_superspec) //MUTATOR_HOOK(MakePlayerObserver, superspec_MakePlayerObserver, CBC_ORDER_ANY); MUTATOR_HOOK(ClientDisconnect, superspec_ClientDisconnect, CBC_ORDER_ANY); - MUTATOR_ONADD - { - } - - MUTATOR_ONREMOVE - { - } - return 0; } diff --git a/qcsrc/server/mutators/sandbox.qc b/qcsrc/server/mutators/sandbox.qc index 4d97b8eec..391e31742 100644 --- a/qcsrc/server/mutators/sandbox.qc +++ b/qcsrc/server/mutators/sandbox.qc @@ -817,6 +817,16 @@ MUTATOR_DEFINITION(sandbox) sandbox_Database_Load(); } + MUTATOR_ONROLLBACK_OR_REMOVE + { + // nothing to roll back + } + + MUTATOR_ONREMOVE + { + // nothing to remove + } + return FALSE; } -- 2.39.2