mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
PluginSystem: add callback for chatroom receiver
Allow plugins to block chat msg's based on their text.
This commit is contained in:
parent
699469f7b6
commit
8cfcc00bc5
@ -177,7 +177,7 @@ CClient* CServer::ConnectClient(CServer* pServer, user_creds_s* pChallenge)
|
||||
|
||||
for (auto& callback : !g_PluginSystem.GetConnectClientCallbacks())
|
||||
{
|
||||
if (!callback(pServer, pClient, pChallenge))
|
||||
if (!callback.Function()(pServer, pClient, pChallenge))
|
||||
{
|
||||
pClient->Disconnect(REP_MARK_BAD, "#Valve_Reject_Banned");
|
||||
return nullptr;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "engine/server/server.h"
|
||||
#include "game/shared/usercmd.h"
|
||||
#include "game/server/util_server.h"
|
||||
#include "pluginsystem/pluginsystem.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This is called when a new game is started. (restart, map)
|
||||
@ -77,8 +78,39 @@ ServerClass* CServerGameDLL::GetAllServerClasses(void)
|
||||
return CallVFunc<ServerClass*>(index, this);
|
||||
}
|
||||
|
||||
static ConVar chat_debug("chat_debug", "0", FCVAR_RELEASE, "Enables chat-related debug printing.");
|
||||
|
||||
void __fastcall CServerGameDLL::OnReceivedSayTextMessage(void* thisptr, int senderId, const char* text, bool isTeamChat)
|
||||
{
|
||||
const CGlobalVars* globals = *g_pGlobals;
|
||||
if (senderId > 0)
|
||||
{
|
||||
if (senderId <= globals->m_nMaxPlayers && senderId != 0xFFFF)
|
||||
{
|
||||
CPlayer* player = reinterpret_cast<CPlayer*>(globals->m_pEdicts[senderId + 30728]);
|
||||
|
||||
if (player && player->IsConnected())
|
||||
{
|
||||
for (auto& cb : !g_PluginSystem.GetChatMessageCallbacks())
|
||||
{
|
||||
if (!cb.Function()(player, text, sv_forceChatToTeamOnly->GetBool()))
|
||||
{
|
||||
if (chat_debug.GetBool())
|
||||
{
|
||||
char moduleName[MAX_PATH] = {};
|
||||
|
||||
V_UnicodeToUTF8(V_UnqualifiedFileName(cb.ModuleName()), moduleName, MAX_PATH);
|
||||
|
||||
Msg(eDLL_T::SERVER, "[%s] Plugin blocked chat message from '%s' (%llu): \"%s\"\n", moduleName, player->GetNetName(), player->GetPlatformUserId(), text);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set isTeamChat to false so that we can let the convar sv_forceChatToTeamOnly decide whether team chat should be enforced
|
||||
// this isn't a great way of doing it but it works so meh
|
||||
CServerGameDLL__OnReceivedSayTextMessage(thisptr, senderId, text, false);
|
||||
|
@ -13,8 +13,12 @@ struct PluginHelpWithAnything_t
|
||||
|
||||
enum class ePluginCallback : int16_t
|
||||
{
|
||||
CModAppSystemGroup_Create = 0,
|
||||
CServer_ConnectClient
|
||||
// !! - WARNING: if any existing values are changed, you must increment INTERFACEVERSION_PLUGINSYSTEM - !!
|
||||
|
||||
CModAppSystemGroup_Create = 0,
|
||||
CServer_ConnectClient = 1,
|
||||
SV_RegisterScriptFunctions = 2,
|
||||
OnReceivedChatMessage = 3,
|
||||
};
|
||||
|
||||
ePluginHelp m_nHelpID;
|
||||
|
@ -131,7 +131,16 @@ CUtlVector<CPluginSystem::PluginInstance_t>& CPluginSystem::GetInstances()
|
||||
//-----------------------------------------------------------------------------
|
||||
void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help)
|
||||
{
|
||||
#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast<fn>(function)
|
||||
#define ADD_PLUGIN_CALLBACK(fn, callback, function) callback += reinterpret_cast<fn>(function); callback.GetCallbacks().Tail().SetModuleName(moduleName)
|
||||
|
||||
if (!help->m_pFunction)
|
||||
return;
|
||||
|
||||
// [rexx]: This fetches the path to the module that contains the requested callback function.
|
||||
// The module name is fetched so that callbacks can be identified by the plugin that they came from.
|
||||
// This must use the wide-char version of this func, as file paths may contain non-ASCII characters and we don't really want those to break.
|
||||
wchar_t moduleName[MAX_PATH] = {};
|
||||
GetMappedFileNameW((HANDLE)-1, help->m_pFunction, moduleName, MAX_PATH);
|
||||
|
||||
switch (help->m_nCallbackID)
|
||||
{
|
||||
@ -145,6 +154,11 @@ void CPluginSystem::AddCallback(PluginHelpWithAnything_t* help)
|
||||
ADD_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction);
|
||||
break;
|
||||
}
|
||||
case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage:
|
||||
{
|
||||
ADD_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -160,6 +174,9 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help)
|
||||
{
|
||||
#define REMOVE_PLUGIN_CALLBACK(fn, callback, function) callback -= reinterpret_cast<fn>(function)
|
||||
|
||||
if (!help->m_pFunction)
|
||||
return;
|
||||
|
||||
switch (help->m_nCallbackID)
|
||||
{
|
||||
case PluginHelpWithAnything_t::ePluginCallback::CModAppSystemGroup_Create:
|
||||
@ -172,6 +189,11 @@ void CPluginSystem::RemoveCallback(PluginHelpWithAnything_t* help)
|
||||
REMOVE_PLUGIN_CALLBACK(ConnectClientFn, GetConnectClientCallbacks(), help->m_pFunction);
|
||||
break;
|
||||
}
|
||||
case PluginHelpWithAnything_t::ePluginCallback::OnReceivedChatMessage:
|
||||
{
|
||||
REMOVE_PLUGIN_CALLBACK(OnChatMessageFn, GetChatMessageCallbacks(), help->m_pFunction);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
class CModAppSystemGroup;
|
||||
class CServer;
|
||||
class CClient;
|
||||
class CPlayer;
|
||||
struct user_creds_s;
|
||||
|
||||
template<typename T>
|
||||
@ -82,6 +83,32 @@ private:
|
||||
CUtlVector<T> m_vCallbacks;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class CPluginCallback
|
||||
{
|
||||
friend class CPluginSystem;
|
||||
public:
|
||||
CPluginCallback(T f) : function(f) {};
|
||||
|
||||
inline const T& Function() { return function; };
|
||||
inline const wchar_t* ModuleName() { return moduleName; };
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return function;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline void SetModuleName(wchar_t* name)
|
||||
{
|
||||
wcscpy_s(moduleName, name);
|
||||
};
|
||||
|
||||
private:
|
||||
T function;
|
||||
wchar_t moduleName[MAX_PATH];
|
||||
};
|
||||
|
||||
class CPluginSystem : IPluginSystem
|
||||
{
|
||||
public:
|
||||
@ -120,10 +147,11 @@ public:
|
||||
|
||||
virtual void* HelpWithAnything(PluginHelpWithAnything_t* help);
|
||||
|
||||
#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList<typeName>& funcName() { return varName; } private: CPluginCallbackList<typeName> varName;
|
||||
#define CREATE_PLUGIN_CALLBACK(typeName, type, funcName, varName) public: using typeName = type; CPluginCallbackList<CPluginCallback<typeName>>& funcName() { return varName; } private: CPluginCallbackList<CPluginCallback<typeName>> varName;
|
||||
|
||||
CREATE_PLUGIN_CALLBACK(CreateFn, bool(*)(CModAppSystemGroup*), GetCreateCallbacks, createCallbacks);
|
||||
CREATE_PLUGIN_CALLBACK(ConnectClientFn, bool(*)(CServer*, CClient*, user_creds_s*), GetConnectClientCallbacks, connectClientCallbacks);
|
||||
CREATE_PLUGIN_CALLBACK(OnChatMessageFn, bool(*)(CPlayer*, const char*, bool), GetChatMessageCallbacks, chatMessageCallbacks);
|
||||
|
||||
#undef CREATE_PLUGIN_CALLBACK
|
||||
|
||||
@ -140,4 +168,4 @@ FORCEINLINE CPluginSystem* PluginSystem()
|
||||
// Monitor this and performance profile this if fps drops are detected.
|
||||
#define CALL_PLUGIN_CALLBACKS(callback, ...) \
|
||||
for (auto& cb : !callback) \
|
||||
cb(__VA_ARGS__)
|
||||
cb.Function()(__VA_ARGS__)
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define INCORRECT_PATH_SEPARATOR_S "/"
|
||||
#define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES ":/\\"
|
||||
#define PATHSEPARATOR(c) ((c) == '\\' || (c) == '/')
|
||||
#define PATHSEPARATORW(c) ((c) == L'\\' || (c) == L'/')
|
||||
#elif POSIX || defined( _PS3 )
|
||||
#define CORRECT_PATH_SEPARATOR '/'
|
||||
#define CORRECT_PATH_SEPARATOR_S "/"
|
||||
@ -14,6 +15,7 @@
|
||||
#define INCORRECT_PATH_SEPARATOR_S "\\"
|
||||
#define CHARACTERS_WHICH_SEPARATE_DIRECTORY_COMPONENTS_IN_PATHNAMES "/"
|
||||
#define PATHSEPARATOR(c) ((c) == '/')
|
||||
#define PATHSEPARATORW(c) ((c) == L'/')
|
||||
#endif
|
||||
|
||||
#define COPY_ALL_CHARACTERS -1
|
||||
@ -156,6 +158,8 @@ inline void V_MakeAbsolutePath(char* pOut, size_t outLen, const char* pPath, con
|
||||
size_t V_StripLastDir(char* dirName, size_t maxLen);
|
||||
// Returns a pointer to the unqualified file name (no path) of a file name
|
||||
const char* V_UnqualifiedFileName(const char* in);
|
||||
const wchar_t* V_UnqualifiedFileName(const wchar_t* in);
|
||||
|
||||
// Given a path and a filename, composes "path\filename", inserting the (OS correct) separator if necessary
|
||||
void V_ComposeFileName(const char* path, const char* filename, char* dest, size_t destSize);
|
||||
|
||||
|
@ -503,8 +503,15 @@ int V_UnicodeToUTF8(const wchar_t* pUnicode, char* pUTF8, int cubDestSizeInBytes
|
||||
cchResult = wcstombs(pUTF8, pUnicode, cubDestSizeInBytes);
|
||||
#endif
|
||||
|
||||
if (cubDestSizeInBytes > 0)
|
||||
pUTF8[cubDestSizeInBytes - 1] = 0;
|
||||
if (cchResult <= 0 || cchResult > cubDestSizeInBytes)
|
||||
{
|
||||
if (cchResult != cubDestSizeInBytes || pUTF8[cubDestSizeInBytes - 1] != '\0')
|
||||
{
|
||||
*pUTF8 = '\0';
|
||||
}
|
||||
}
|
||||
else
|
||||
pUTF8[cchResult] = '\0';
|
||||
|
||||
return cchResult;
|
||||
}
|
||||
@ -1248,6 +1255,26 @@ const char* V_UnqualifiedFileName(const char* in)
|
||||
return out;
|
||||
}
|
||||
|
||||
const wchar_t* V_UnqualifiedFileName(const wchar_t* in)
|
||||
{
|
||||
Assert(in);
|
||||
|
||||
const wchar_t* out = in;
|
||||
|
||||
while (*in)
|
||||
{
|
||||
if (PATHSEPARATORW(*in))
|
||||
{
|
||||
// +1 to skip the slash
|
||||
out = in + 1;
|
||||
}
|
||||
|
||||
in++;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Composes a path and filename together, inserting a path separator
|
||||
// if need be
|
||||
|
Loading…
x
Reference in New Issue
Block a user