diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 0a7641f..07daf1d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,7 +31,8 @@ jobs: if: runner.os == 'Linux' run: | sudo apt-get update - sudo apt-get install -y clang python3-pip + sudo apt-get install -y clang-16 python3-pip + ln -sf /usr/bin/clang-16 /usr/bin/clang && ln -sf /usr/bin/clang++-16 /usr/bin/clang++ echo "CC=clang" >> $GITHUB_ENV echo "CXX=clang++" >> $GITHUB_ENV clang --version diff --git a/AMBuildScript b/AMBuildScript index dd1264a..5bb72a9 100644 --- a/AMBuildScript +++ b/AMBuildScript @@ -136,7 +136,7 @@ class MMSPluginConfig(object): '-fPIC', ] - cxx.cxxflags += ['-std=c++17'] + cxx.cxxflags += ['-std=c++20'] if (cxx.version >= 'gcc-4.0') or cxx.family == 'clang': cxx.cflags += ['-fvisibility=hidden'] cxx.cxxflags += ['-fvisibility-inlines-hidden'] @@ -184,7 +184,7 @@ class MMSPluginConfig(object): cxx.cflags += [ '/W3', '/Zi', - '/std:c++17', + '/std:c++20', ] cxx.cxxflags += ['/TP'] diff --git a/src/client_cvar_value.cpp b/src/client_cvar_value.cpp index 460206e..5c0528a 100644 --- a/src/client_cvar_value.cpp +++ b/src/client_cvar_value.cpp @@ -15,6 +15,7 @@ */ #include "client_cvar_value.h" +#include "sdk/recipientfilters.h" #include #include #include @@ -146,8 +147,8 @@ int ClientCvarValue::SendCvarValueQueryToClient(CPlayerSlot nSlot, const char* p msg->set_cookie(iQueryCvarCookie); msg->set_cvar_name(pszCvarName); - uint64 clients = { 1llu << nSlot.Get() }; - g_pGameEventSystem->PostEventAbstract(-1, false, nSlot.Get() + 1, &clients, pMsg, msg, 0, BUF_RELIABLE); + CSingleRecipientFilter filter(nSlot); + g_pGameEventSystem->PostEventAbstract(0, false, &filter, pMsg, msg, 0); delete msg; @@ -210,7 +211,7 @@ const char* ClientCvarValue::GetLicense() const char* ClientCvarValue::GetVersion() { - return "1.0.8"; + return "1.0.9"; } const char* ClientCvarValue::GetDate() @@ -225,7 +226,7 @@ const char* ClientCvarValue::GetLogTag() const char* ClientCvarValue::GetAuthor() { - return u8"Phoenix (˙·٠●Феникс●٠·˙)"; + return "Phoenix (˙·٠●Феникс●٠·˙)"; } const char* ClientCvarValue::GetDescription() diff --git a/src/sdk/recipientfilters.h b/src/sdk/recipientfilters.h new file mode 100644 index 0000000..36720a0 --- /dev/null +++ b/src/sdk/recipientfilters.h @@ -0,0 +1,56 @@ +#pragma once +#include "irecipientfilter.h" +#include + +class CRecipientFilter : public IRecipientFilter +{ +public: + CRecipientFilter(NetChannelBufType_t nBufType = BUF_RELIABLE, bool bInitMessage = false) : + m_nBufType(nBufType), m_bInitMessage(bInitMessage) {} + + CRecipientFilter(IRecipientFilter* source, CPlayerSlot exceptSlot = -1) + { + m_Recipients = source->GetRecipients(); + m_nBufType = source->GetNetworkBufType(); + m_bInitMessage = source->IsInitMessage(); + + if (exceptSlot != -1) + m_Recipients.Clear(exceptSlot.Get()); + } + + ~CRecipientFilter() override {} + + NetChannelBufType_t GetNetworkBufType(void) const override { return m_nBufType; } + bool IsInitMessage(void) const override { return m_bInitMessage; } + const CPlayerBitVec& GetRecipients(void) const override { return m_Recipients; } + + void AddRecipient(CPlayerSlot slot) + { + if (slot.Get() >= 0 && slot.Get() < ABSOLUTE_PLAYER_LIMIT) + m_Recipients.Set(slot.Get()); + } + + int GetRecipientCount() + { + const uint64 bits = *reinterpret_cast(&GetRecipients()); + + return std::popcount(bits); + } + +protected: + NetChannelBufType_t m_nBufType; + bool m_bInitMessage; + CPlayerBitVec m_Recipients; +}; + +// Simple filter for when only 1 recipient is needed +class CSingleRecipientFilter : public CRecipientFilter +{ +public: + CSingleRecipientFilter(CPlayerSlot nRecipientSlot, NetChannelBufType_t nBufType = BUF_RELIABLE, bool bInitMessage = false) : + CRecipientFilter(nBufType, bInitMessage) + { + if (nRecipientSlot.Get() >= 0 && nRecipientSlot.Get() < ABSOLUTE_PLAYER_LIMIT) + m_Recipients.Set(nRecipientSlot.Get()); + } +};