From e162af0003f7d497eafb3c2936eeb527f8b888cb Mon Sep 17 00:00:00 2001 From: Koncord Date: Tue, 30 Oct 2018 15:32:52 +0800 Subject: [PATCH] [Server] Disallow non void callbacks --- apps/openmw-mp/Script/Script.hpp | 39 +------- apps/openmw-mp/Script/ScriptFunctions.hpp | 112 +++++++++++----------- apps/openmw-mp/Script/Types.hpp | 20 +++- 3 files changed, 75 insertions(+), 96 deletions(-) diff --git a/apps/openmw-mp/Script/Script.hpp b/apps/openmw-mp/Script/Script.hpp index 6e80c4c47..713f6550d 100644 --- a/apps/openmw-mp/Script/Script.hpp +++ b/apps/openmw-mp/Script/Script.hpp @@ -62,49 +62,12 @@ public: return callbacks[N].index == I ? callbacks[N] : CallBackData(I, N + 1); } - template - using CallBackReturn = typename CharType::type; - template static constexpr unsigned int CallbackIdentity(const char(&str)[N]) { return Utils::hash(str); } - - template - static unsigned int Call(CallBackReturn& result, Args&&... args) { - constexpr ScriptCallbackData const& data = CallBackData(I); - static_assert(data.callback.matches(TypeString::type...>::value), - "Wrong number or types of arguments"); - - unsigned int count = 0; - - for (auto& script : scripts) - { - if (!script->callbacks_.count(I)) - script->callbacks_.emplace(I, script->GetScript>(data.name)); - - auto callback = script->callbacks_[I]; - - if (!callback) - continue; - - if (script->script_type == SCRIPT_CPP) - result = reinterpret_cast>>(callback)(std::forward(args)...); -#if defined (ENABLE_LUA) - else if (script->script_type == SCRIPT_LUA) - { - boost::any any = script->lang->Call(data.name, data.callback.types, B, std::forward(args)...); - result = static_cast>(boost::any_cast(any).cast>()); - } -#endif - ++count; - } - - return count; - } - template static unsigned int Call(Args&&... args) { constexpr ScriptCallbackData const& data = CallBackData(I); @@ -124,7 +87,7 @@ public: continue; if (script->script_type == SCRIPT_CPP) - reinterpret_cast>>(callback)(std::forward(args)...); + (callback)(std::forward(args)...); #if defined (ENABLE_LUA) else if (script->script_type == SCRIPT_LUA) script->lang->Call(data.name, data.callback.types, B, std::forward(args)...); diff --git a/apps/openmw-mp/Script/ScriptFunctions.hpp b/apps/openmw-mp/Script/ScriptFunctions.hpp index 192aed255..1c337f102 100644 --- a/apps/openmw-mp/Script/ScriptFunctions.hpp +++ b/apps/openmw-mp/Script/ScriptFunctions.hpp @@ -150,62 +150,62 @@ public: }; static constexpr ScriptCallbackData callbacks[]{ - {"OnServerInit", Function()}, - {"OnServerPostInit", Function()}, - {"OnServerExit", Function()}, - {"OnPlayerConnect", Function()}, - {"OnPlayerDisconnect", Function()}, - {"OnPlayerDeath", Function()}, - {"OnPlayerResurrect", Function()}, - {"OnPlayerCellChange", Function()}, - {"OnPlayerAttribute", Function()}, - {"OnPlayerSkill", Function()}, - {"OnPlayerLevel", Function()}, - {"OnPlayerBounty", Function()}, - {"OnPlayerReputation", Function()}, - {"OnPlayerEquipment", Function()}, - {"OnPlayerInventory", Function()}, - {"OnPlayerJournal", Function()}, - {"OnPlayerFaction", Function()}, - {"OnPlayerShapeshift", Function()}, - {"OnPlayerSpellbook", Function()}, - {"OnPlayerQuickKeys", Function()}, - {"OnPlayerTopic", Function()}, - {"OnPlayerDisposition", Function()}, - {"OnPlayerBook", Function()}, - {"OnPlayerItemUse", Function()}, - {"OnPlayerMiscellaneous", Function()}, - {"OnPlayerInput", Function()}, - {"OnPlayerRest", Function()}, - {"OnRecordDynamic", Function()}, - {"OnCellLoad", Function()}, - {"OnCellUnload", Function()}, - {"OnCellDeletion", Function()}, - {"OnContainer", Function()}, - {"OnDoorState", Function()}, - {"OnObjectActivate", Function()}, - {"OnObjectPlace", Function()}, - {"OnObjectState", Function()}, - {"OnObjectSpawn", Function()}, - {"OnObjectDelete", Function()}, - {"OnObjectLock", Function()}, - {"OnObjectScale", Function()}, - {"OnObjectTrap", Function()}, - {"OnVideoPlay", Function()}, - {"OnActorList", Function()}, - {"OnActorEquipment", Function()}, - {"OnActorAI", Function()}, - {"OnActorDeath", Function()}, - {"OnActorCellChange", Function()}, - {"OnActorTest", Function()}, - {"OnPlayerSendMessage", Function()}, - {"OnPlayerEndCharGen", Function()}, - {"OnGUIAction", Function()}, - {"OnWorldKillCount", Function()}, - {"OnWorldMap", Function()}, - {"OnWorldWeather", Function() }, - {"OnMpNumIncrement", Function()}, - {"OnRequestPluginList", Function()} + {"OnServerInit", Callback<>()}, + {"OnServerPostInit", Callback<>()}, + {"OnServerExit", Callback()}, + {"OnPlayerConnect", Callback()}, + {"OnPlayerDisconnect", Callback()}, + {"OnPlayerDeath", Callback()}, + {"OnPlayerResurrect", Callback()}, + {"OnPlayerCellChange", Callback()}, + {"OnPlayerAttribute", Callback()}, + {"OnPlayerSkill", Callback()}, + {"OnPlayerLevel", Callback()}, + {"OnPlayerBounty", Callback()}, + {"OnPlayerReputation", Callback()}, + {"OnPlayerEquipment", Callback()}, + {"OnPlayerInventory", Callback()}, + {"OnPlayerJournal", Callback()}, + {"OnPlayerFaction", Callback()}, + {"OnPlayerShapeshift", Callback()}, + {"OnPlayerSpellbook", Callback()}, + {"OnPlayerQuickKeys", Callback()}, + {"OnPlayerTopic", Callback()}, + {"OnPlayerDisposition", Callback()}, + {"OnPlayerBook", Callback()}, + {"OnPlayerItemUse", Callback()}, + {"OnPlayerMiscellaneous", Callback()}, + {"OnPlayerInput", Callback()}, + {"OnPlayerRest", Callback()}, + {"OnRecordDynamic", Callback()}, + {"OnCellLoad", Callback()}, + {"OnCellUnload", Callback()}, + {"OnCellDeletion", Callback()}, + {"OnContainer", Callback()}, + {"OnDoorState", Callback()}, + {"OnObjectActivate", Callback()}, + {"OnObjectPlace", Callback()}, + {"OnObjectState", Callback()}, + {"OnObjectSpawn", Callback()}, + {"OnObjectDelete", Callback()}, + {"OnObjectLock", Callback()}, + {"OnObjectScale", Callback()}, + {"OnObjectTrap", Callback()}, + {"OnVideoPlay", Callback()}, + {"OnActorList", Callback()}, + {"OnActorEquipment", Callback()}, + {"OnActorAI", Callback()}, + {"OnActorDeath", Callback()}, + {"OnActorCellChange", Callback()}, + {"OnActorTest", Callback()}, + {"OnPlayerSendMessage", Callback()}, + {"OnPlayerEndCharGen", Callback()}, + {"OnGUIAction", Callback()}, + {"OnWorldKillCount", Callback()}, + {"OnWorldMap", Callback()}, + {"OnWorldWeather", Callback() }, + {"OnMpNumIncrement", Callback()}, + {"OnRequestPluginList", Callback<>()} }; }; diff --git a/apps/openmw-mp/Script/Types.hpp b/apps/openmw-mp/Script/Types.hpp index adcf7b29a..88f4ce834 100644 --- a/apps/openmw-mp/Script/Types.hpp +++ b/apps/openmw-mp/Script/Types.hpp @@ -82,6 +82,22 @@ struct ScriptIdentity constexpr ScriptIdentity(Function) : types(TypeString::value), ret(TypeChar::value>::value), numargs(sizeof(TypeString::value) - 1) {} }; +template +using Callback = void (*)(Types...); + +struct CallbackIdentity +{ + const char* types; + const unsigned int numargs; + + constexpr bool matches(const char* types, const unsigned int N = 0) const + { + return N < numargs ? this->types[N] == types[N] && matches(types, N + 1) : this->types[N] == types[N]; + } + + template + constexpr CallbackIdentity(Callback) : types(TypeString::value), numargs(sizeof(TypeString::value) - 1) {} +}; struct ScriptFunctionPointer : public ScriptIdentity @@ -104,10 +120,10 @@ struct ScriptCallbackData { const char* name; const unsigned int index; - const ScriptIdentity callback; + const CallbackIdentity callback; template - constexpr ScriptCallbackData(const char(&name)[N], ScriptIdentity _callback) : name(name), index(Utils::hash(name)), callback(_callback) {} + constexpr ScriptCallbackData(const char(&name)[N], CallbackIdentity _callback) : name(name), index(Utils::hash(name)), callback(_callback) {} }; #endif //TMPTYPES_HPP