Skip to content

Add access to CGameRules and its properties #363

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 21, 2020
Prev Previous commit
Next Next commit
Reimplemented gamerules functions using string tables
  • Loading branch information
Ayuto committed Dec 11, 2020
commit fceb3a668a4f4e700699136c78487ca74a141286
86 changes: 30 additions & 56 deletions src/core/modules/engines/engines_gamerules.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,21 @@
#include "boost/python.hpp"
using namespace boost::python;

// SDK
#include "strtools.h"

//---------------------------------------------------------------------------------
// External variables to use.
//---------------------------------------------------------------------------------
extern INetworkStringTableContainer *networkstringtable;


//-----------------------------------------------------------------------------
// Functions
//-----------------------------------------------------------------------------
int find_game_rules_property_offset(const char* name)
{
// TODO: I guess it's save to cache the server class...

CBaseEntityWrapper* proxy = (CBaseEntityWrapper*) CBaseEntityWrapper::find_or_create(find_game_rules_proxy_name());

ServerClass* cls = proxy->GetServerClass();
if (!cls)
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Failed to retrieve the server class.")
ServerClass* cls = ServerClassExt::find_server_class(find_game_rules_proxy_name());
int offset = SendTableSharedExt::find_offset(cls->m_pTable, name);

int offset;
offset = SendTableSharedExt::find_offset(cls->m_pTable, name);
if (offset == -1)
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to find property '%s'.", name)

Expand All @@ -66,65 +62,43 @@ int find_game_rules_property_offset(const char* name)
const char* find_game_rules_proxy_name()
{
static const char* s_proxy_name = NULL;
int i = 0;

if (s_proxy_name)
{
return s_proxy_name;
}

CEntityFactoryDictionary* factory_dictionary = GetEntityFactoryDictionary();

while (factory_dictionary->m_Factories.IsValidIndex(i))
{
const char* classname = factory_dictionary->m_Factories.GetElementName(i);
if (V_stristr(classname, "gamerules"))
{
// Cache the result
s_proxy_name = classname;
return classname;
}

++i;
}

BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to find game rules proxy name.");
return NULL;
}

CGameRulesWrapper* find_game_rules()
SendTableProxyFn find_game_rules_proxy_function()
{
// TODO: Can we cache the result?
SendTableProxyFn s_proxy_func = NULL;
if (s_proxy_func)
return s_proxy_func;

CBaseEntityWrapper* proxy = (CBaseEntityWrapper*) CBaseEntityWrapper::find_or_create(find_game_rules_proxy_name());
ServerClass* cls = ServerClassExt::find_server_class(find_game_rules_proxy_name());
SendTable* table = cls->m_pTable;

ServerClass* cls = proxy->GetServerClass();
while (cls)
for (int i=0; i < table->GetNumProps(); i++)
{
SendTable* table = cls->m_pTable;
for (int i=0; i < table->GetNumProps(); i++)
SendProp* prop = table->GetProp(i);
if (!V_stristr(prop->GetName(), "gamerules_data"))
{
SendProp* prop = table->GetProp(i);
if (!V_stristr(prop->GetName(), "gamerules_data"))
{
continue;
}

SendTableProxyFn proxy_func = prop->GetDataTableProxyFn();
if (!proxy_func)
{
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Found game rules proxy entity, but proxy function is NULL.");
}

// Pass the recipients. Some game's proxy functions require it for
// the game rules proxy.
CSendProxyRecipients recipients;
return (CGameRulesWrapper*) proxy_func(NULL, NULL, NULL, &recipients, 0);
continue;
}

cls = cls->m_pNext;
SendTableProxyFn s_proxy_func = prop->GetDataTableProxyFn();
if (!s_proxy_func)
{
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Game rules proxy function is NULL.");
}
}

BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Found game rules proxy entity, but proxy function is NULL.");
return NULL;
}

CGameRulesWrapper* find_game_rules()
{
SendTableProxyFn proxy_func = find_game_rules_proxy_function();
static CSendProxyRecipients recipients;

return (CGameRulesWrapper*) proxy_func(NULL, NULL, NULL, &recipients, 0);
}