Skip to content

Commit b5bb646

Browse files
authored
Add access to CGameRules and its properties (#363)
* Add back game rules * Initial commit Since the Linux build doesn't like running with opaque types, I had to change back a lot... * Moved stringtables stuff to the appropriate files Fixed StringTable.changed_since_tick() calling the wrong C++ function * Added static method ServerClass.find_server_class() * Added back those two * Reimplemented gamerules functions using string tables * Cleanup, sanity checks and typos * Fixed spacing * Cache SendTable
1 parent 9d6c9e0 commit b5bb646

File tree

12 files changed

+849
-138
lines changed

12 files changed

+849
-138
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
engines.gamerules module
2+
=========================
3+
4+
.. automodule:: engines.gamerules
5+
:members:
6+
:undoc-members:
7+
:show-inheritance:
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# ../engines/gamerules.py
2+
3+
"""Provides access to the gamerules instance."""
4+
5+
# =============================================================================
6+
# >> FORWARD IMPORTS
7+
# =============================================================================
8+
# Source.Python Imports
9+
# Engines
10+
from _engines._gamerules import GameRules
11+
from _engines._gamerules import find_game_rules_property_offset
12+
from _engines._gamerules import find_game_rules
13+
from _engines._gamerules import find_game_rules_proxy_name
14+
15+
16+
# =============================================================================
17+
# >> ALL DECLARATION
18+
# =============================================================================
19+
__all__ = (
20+
'GameRules',
21+
'find_game_rules_property_offset',
22+
'find_game_rules',
23+
'find_game_rules_proxy_name',)

src/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ Set(SOURCEPYTHON_ENGINES_MODULE_HEADERS
195195
core/modules/engines/engines_server.h
196196
core/modules/engines/${SOURCE_ENGINE}/engines.h
197197
core/modules/engines/${SOURCE_ENGINE}/engines_wrap.h
198+
core/modules/engines/engines_gamerules.h
198199
)
199200

200201
Set(SOURCEPYTHON_ENGINES_MODULE_SOURCES
@@ -203,6 +204,8 @@ Set(SOURCEPYTHON_ENGINES_MODULE_SOURCES
203204
core/modules/engines/engines_server_wrap.cpp
204205
core/modules/engines/engines_sound_wrap.cpp
205206
core/modules/engines/engines_trace_wrap.cpp
207+
core/modules/engines/engines_gamerules.cpp
208+
core/modules/engines/engines_gamerules_wrap.cpp
206209
)
207210

208211
# ------------------------------------------------------------------
@@ -435,9 +438,11 @@ Set(SOURCEPYTHON_STEAM_MODULE_SOURCES
435438
# StringTables module.
436439
# ------------------------------------------------------------------
437440
Set(SOURCEPYTHON_STRINGTABLES_MODULE_HEADERS
441+
core/modules/stringtables/stringtables.h
438442
)
439443

440444
Set(SOURCEPYTHON_STRINGTABLES_MODULE_SOURCES
445+
core/modules/stringtables/stringtables.cpp
441446
core/modules/stringtables/stringtables_wrap.cpp
442447
)
443448

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/**
2+
* =============================================================================
3+
* Source Python
4+
* Copyright (C) 2012-2020 Source Python Development Team. All rights reserved.
5+
* =============================================================================
6+
*
7+
* This program is free software; you can redistribute it and/or modify it under
8+
* the terms of the GNU General Public License, version 3.0, as published by the
9+
* Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14+
* details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with
17+
* this program. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
* As a special exception, the Source Python Team gives you permission
20+
* to link the code of this program (as well as its derivative works) to
21+
* "Half-Life 2," the "Source Engine," and any Game MODs that run on software
22+
* by the Valve Corporation. You must obey the GNU General Public License in
23+
* all respects for all other code used. Additionally, the Source.Python
24+
* Development Team grants this exception to all derivative works.
25+
*/
26+
27+
//-----------------------------------------------------------------------------
28+
// Includes.
29+
//-----------------------------------------------------------------------------
30+
// Source.Python
31+
#include "engines_gamerules.h"
32+
#include "modules/entities/entities_props.h"
33+
#include "modules/stringtables/stringtables.h"
34+
#include "utilities/wrap_macros.h"
35+
36+
// Boost.Python
37+
#include "boost/python.hpp"
38+
using namespace boost::python;
39+
40+
// SDK
41+
#include "server_class.h"
42+
43+
44+
//---------------------------------------------------------------------------------
45+
// External variables to use.
46+
//---------------------------------------------------------------------------------
47+
extern INetworkStringTableContainer *networkstringtable;
48+
49+
50+
//-----------------------------------------------------------------------------
51+
// Functions
52+
//-----------------------------------------------------------------------------
53+
int find_game_rules_property_offset(const char* name)
54+
{
55+
static SendTable* s_table = NULL;
56+
if (!s_table)
57+
{
58+
ServerClass* cls = ServerClassExt::find_server_class(find_game_rules_proxy_name());
59+
s_table = cls->m_pTable;
60+
}
61+
62+
int offset = SendTableSharedExt::find_offset(s_table, name);
63+
64+
if (offset == -1)
65+
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to find property '%s'.", name)
66+
67+
return offset;
68+
}
69+
70+
const char* find_game_rules_proxy_name()
71+
{
72+
static std::string s_proxy_name;
73+
if (!s_proxy_name.empty())
74+
// Use cache
75+
return s_proxy_name.c_str();
76+
77+
INetworkStringTable* table = networkstringtable->FindTable("GameRulesCreation");
78+
if (!table)
79+
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Unable to find string table 'GameRulesCreation'.")
80+
81+
s_proxy_name = INetworkStringTableExt::GetStringUserData(table, "classname");
82+
if (s_proxy_name.empty())
83+
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "'classname' of string table 'GameRulesCreation' is NULL.")
84+
85+
s_proxy_name += "Proxy";
86+
return s_proxy_name.c_str();
87+
}
88+
89+
SendTableProxyFn find_game_rules_proxy_function()
90+
{
91+
SendTableProxyFn s_proxy_func = NULL;
92+
if (s_proxy_func)
93+
// Use cache
94+
return s_proxy_func;
95+
96+
ServerClass* cls = ServerClassExt::find_server_class(find_game_rules_proxy_name());
97+
SendTable* table = cls->m_pTable;
98+
99+
for (int i=0; i < table->GetNumProps(); i++)
100+
{
101+
SendProp* prop = table->GetProp(i);
102+
if (!V_stristr(prop->GetName(), "gamerules_data"))
103+
continue;
104+
105+
s_proxy_func = prop->GetDataTableProxyFn();
106+
break;
107+
}
108+
109+
if (!s_proxy_func)
110+
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Game rules proxy function is NULL.");
111+
112+
return s_proxy_func;
113+
}
114+
115+
CGameRulesWrapper* find_game_rules()
116+
{
117+
SendTableProxyFn proxy_func = find_game_rules_proxy_function();
118+
static CSendProxyRecipients recipients;
119+
120+
CGameRulesWrapper* game_rules = (CGameRulesWrapper*) proxy_func(NULL, NULL, NULL, &recipients, 0);
121+
if (!game_rules)
122+
BOOST_RAISE_EXCEPTION(PyExc_ValueError, "Game rules pointer is NULL.");
123+
124+
return game_rules;
125+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/**
2+
* =============================================================================
3+
* Source Python
4+
* Copyright (C) 2012-2020 Source Python Development Team. All rights reserved.
5+
* =============================================================================
6+
*
7+
* This program is free software; you can redistribute it and/or modify it under
8+
* the terms of the GNU General Public License, version 3.0, as published by the
9+
* Free Software Foundation.
10+
*
11+
* This program is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14+
* details.
15+
*
16+
* You should have received a copy of the GNU General Public License along with
17+
* this program. If not, see <http://www.gnu.org/licenses/>.
18+
*
19+
* As a special exception, the Source Python Team gives you permission
20+
* to link the code of this program (as well as its derivative works) to
21+
* "Half-Life 2," the "Source Engine," and any Game MODs that run on software
22+
* by the Valve Corporation. You must obey the GNU General Public License in
23+
* all respects for all other code used. Additionally, the Source.Python
24+
* Development Team grants this exception to all derivative works.
25+
*/
26+
27+
#ifndef _ENGINES_GAMERULES_H
28+
#define _ENGINES_GAMERULES_H
29+
30+
//-----------------------------------------------------------------------------
31+
// Includes.
32+
//-----------------------------------------------------------------------------
33+
// SDK
34+
#include "strtools.h"
35+
36+
37+
//-----------------------------------------------------------------------------
38+
// Functions
39+
//-----------------------------------------------------------------------------
40+
class CGameRulesWrapper;
41+
42+
int find_game_rules_property_offset(const char* name);
43+
const char* find_game_rules_proxy_name();
44+
CGameRulesWrapper* find_game_rules();
45+
46+
47+
//-----------------------------------------------------------------------------
48+
// Classes.
49+
//-----------------------------------------------------------------------------
50+
class CGameRulesWrapper
51+
{
52+
public:
53+
54+
// Getter methods
55+
template<class T>
56+
T GetProperty(const char* name)
57+
{
58+
return GetPropertyByOffset<T>(find_game_rules_property_offset(name));
59+
}
60+
61+
template<class T>
62+
T GetPropertyByOffset(int offset)
63+
{
64+
return *(T *) (((unsigned long) this) + offset);
65+
}
66+
67+
const char* GetPropertyStringArray(const char* name)
68+
{
69+
return GetPropertyStringArrayByOffset(find_game_rules_property_offset(name));
70+
}
71+
72+
const char* GetPropertyStringArrayByOffset(int offset)
73+
{
74+
return (const char*) (((unsigned long) this) + offset);
75+
}
76+
77+
// Setter methods
78+
template<class T>
79+
void SetProperty(const char* name, T value)
80+
{
81+
SetPropertyByOffset<T>(find_game_rules_property_offset(name), value);
82+
}
83+
84+
template<class T>
85+
void SetPropertyByOffset(int offset, T value)
86+
{
87+
*(T *) (((unsigned long) this) + offset) = value;
88+
}
89+
90+
void SetPropertyStringArray(const char* name, const char* value)
91+
{
92+
SetPropertyStringArrayByOffset(find_game_rules_property_offset(name), value);
93+
}
94+
95+
void SetPropertyStringArrayByOffset(int offset, const char* value)
96+
{
97+
strcpy((char*) (((unsigned long) this) + offset), value);
98+
}
99+
};
100+
101+
#endif // _ENGINES_GAMERULES_H

0 commit comments

Comments
 (0)