From 7eef3948b13c61f4dda8866720c6d3f7d11fe1c4 Mon Sep 17 00:00:00 2001 From: Peace-Maker Date: Fri, 4 Aug 2017 12:52:19 +0200 Subject: [PATCH] Don't break backwards compatibility with unmanaged forwards Instead of adding new functions to `IForward`, we just allow NULL to be passed to `PushArray` and `PushString`. --- core/logic/ForwardSys.cpp | 17 +++++++++++++++-- core/logic/ForwardSys.h | 4 ++-- core/logic/smn_functions.cpp | 4 ++-- public/IForwardSys.h | 23 ++++++++--------------- 4 files changed, 27 insertions(+), 21 deletions(-) diff --git a/core/logic/ForwardSys.cpp b/core/logic/ForwardSys.cpp index f599cb56..bc31f7f7 100644 --- a/core/logic/ForwardSys.cpp +++ b/core/logic/ForwardSys.cpp @@ -528,10 +528,17 @@ void CForward::_Int_PushArray(cell_t *inarray, unsigned int cells, int flags) int CForward::PushArray(cell_t *inarray, unsigned int cells, int flags) { - /* We don't allow this here */ + /* Push a reference to the NULL_VECTOR pubvar if NULL was passed. */ if (!inarray) { - return SetError(SP_ERROR_PARAM); + /* Make sure this was intentional. */ + if (cells == 3) + { + return PushNullVector(); + } else { + /* We don't allow this here */ + return SetError(SP_ERROR_PARAM); + } } if (m_curparam < m_numparams) @@ -568,6 +575,12 @@ void CForward::_Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags int CForward::PushString(const char *string) { + /* Push a reference to the NULL_STRING pubvar if NULL was passed. */ + if (!string) + { + return PushNullString(); + } + if (m_curparam < m_numparams) { if (m_types[m_curparam] == Param_Any) diff --git a/core/logic/ForwardSys.h b/core/logic/ForwardSys.h index b5037b2d..cd1b3b82 100644 --- a/core/logic/ForwardSys.h +++ b/core/logic/ForwardSys.h @@ -55,8 +55,6 @@ public: //IForward virtual unsigned int GetFunctionCount(); virtual ExecType GetExecType(); virtual int Execute(cell_t *result, IForwardFilter *filter); - virtual int PushNullString(); - virtual int PushNullVector(); public: //IChangeableForward virtual bool RemoveFunction(IPluginFunction *func); virtual unsigned int RemoveFunctionsOfPlugin(IPlugin *plugin); @@ -74,6 +72,8 @@ private: CForward(ExecType et, const char *name, const ParamType *types, unsigned num_params); + int PushNullString(); + int PushNullVector(); int _ExecutePushRef(IPluginFunction *func, ParamType type, FwdParamInfo *param); void _Int_PushArray(cell_t *inarray, unsigned int cells, int flags); void _Int_PushString(cell_t *inarray, unsigned int cells, int sz_flags, int cp_flags); diff --git a/core/logic/smn_functions.cpp b/core/logic/smn_functions.cpp index ef66c493..792da977 100644 --- a/core/logic/smn_functions.cpp +++ b/core/logic/smn_functions.cpp @@ -580,7 +580,7 @@ static cell_t sm_CallPushNullVector(IPluginContext *pContext, const cell_t *para } else if (s_pForward) { - err = s_pForward->PushNullVector(); + err = s_pForward->PushArray(NULL, 3); } if (err) @@ -621,7 +621,7 @@ static cell_t sm_CallPushNullString(IPluginContext *pContext, const cell_t *para } else if (s_pForward) { - err = s_pForward->PushNullString(); + err = s_pForward->PushString(NULL); } if (err) diff --git a/public/IForwardSys.h b/public/IForwardSys.h index 9040d549..cbd59abb 100644 --- a/public/IForwardSys.h +++ b/public/IForwardSys.h @@ -178,7 +178,8 @@ namespace SourceMod * @brief Pushes an array of cells onto the current call. Different rules than ICallable. * NOTE: On Execute, the pointer passed will be modified according to the copyback rule. * - * @param inarray Array to copy. Cannot be NULL, unlike ICallable's version. + * @param inarray Array to copy. If NULL and cells is 3 pushes a reference to the NULL_VECTOR pubvar to each callee. + * Pushing other number of cells is not allowed, unlike ICallable's version. * @param cells Number of cells to allocate and optionally read from the input array. * @param flags Whether or not changes should be copied back to the input array. * @return Error code, if any. @@ -186,20 +187,12 @@ namespace SourceMod virtual int PushArray(cell_t *inarray, unsigned int cells, int flags=0) =0; /** - * @brief Pushes the NULL_STRING onto the current call. This will always push the - * correct reference to each function in the forward. - * - * @return Error code, if any. - */ - virtual int PushNullString() =0; - - /** - * @brief Pushes the NULL_VECTOR onto the current call. This will always push the - * correct reference to each function in the forward. - * - * @return Error code, if any. - */ - virtual int PushNullVector() =0; + * @brief Pushes a string onto the current call. + * + * @param string String to push. If NULL pushes a reference to the NULL_STRING pubvar to each callee. + * @return Error code, if any. + */ + virtual int PushString(const char *string) = 0; }; /**