Skip to content

Commit 4d79f16

Browse files
committed
Added a small bit of error checking.
If a player caused player_airborn or player_landed to fire but disconnected or became invalid on the next frame then GetPawn() would error due to pc being nullptr. TestPlayerJump.py added cleanup on disconnect to remove a players entries in the last_grounded and players_in_air dicts. Usage of ADVPlayer.GetName() will either return const char* or nullptr. typo in pyplugins.ini starting on TestPlayerInputs.py
1 parent bc824f0 commit 4d79f16

File tree

8 files changed

+134
-10
lines changed

8 files changed

+134
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ bld/
2424
/configs/admins.cfg
2525
/data/infractions.txt
2626
dump
27+
Adventure

PyPlugins/pyplugins.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,12 @@ tests/TestPlayerJump.py
2828
## event 'OnPlayerLand'
2929
## event 'OnPlayerAirborn'
3030

31+
tests/TestPlayerInputs.py
32+
## buttons'n'bindings and stuff in here, lets see.
3133

3234
##junk below is old work to pull from while making
3335
##'good' working examples above
3436
#SampleEvents.py
35-
#ManyRaces/AdventureTest.py
37+
#ManyRaces/AdventureTest.py
38+
39+
adventure/adventure.py
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import Source2Py
2+
ADVPlayer = Source2Py.ADVPlayer
3+
4+
import logging, inspect, traceback
5+
6+
logging.basicConfig(filename='tests/TestPlayerInputs.log', encoding='utf-8', level=logging.DEBUG, format='[%(asctime)s]%(message)s', datefmt='%H:%M:%S')
7+
log = logging
8+
9+
def alog(message: str, callername: bool = True):
10+
caller = str("")
11+
if (callername):
12+
caller = "[" + str(inspect.stack()[1].function) + "] "
13+
Source2Py.ServerPrint("[TestPlayerInputs]" + caller + str(message))
14+
log.info(msg=("[TestPlayerInputs]" + caller + str(message)))
15+
pass
16+
17+
alog("START")
18+
class TestPlayerInputs:
19+
def OnPluginLoad(self):
20+
alog("")
21+
pass
22+
23+
def OnGameFrame(self,
24+
simulating: bool,
25+
bFirstTick: bool,
26+
bLastTick: bool
27+
):
28+
29+
pass
30+
def OnPlayer______(self,
31+
_slot: int
32+
):
33+
alog("START")
34+
try:
35+
alog("_slot: " + str(_slot))
36+
player = ADVPlayer(_slot)
37+
alog(player.GetName() + " is airborn!")
38+
except Exception as e:
39+
alog(e)
40+
alog(traceback.format_exc())
41+
alog("END")
42+
pass
43+
44+
45+
'''button_flags =
46+
{
47+
"IN_NONE": 0x0,
48+
"IN_ALL": 0xffffffffffffffff,
49+
"IN_ATTACK": 0x1,
50+
"IN_JUMP": 0x2,
51+
"IN_DUCK": 0x4,
52+
"IN_FORWARD": 0x8,
53+
"IN_BACK": 0x10,
54+
"IN_USE": 0x20,
55+
"IN_TURNLEFT": 0x80,
56+
"IN_TURNRIGHT": 0x100,
57+
"IN_MOVELEFT": 0x200,
58+
"IN_MOVERIGHT": 0x400,
59+
"IN_ATTACK2": 0x800,
60+
"IN_RELOAD": 0x2000,
61+
"IN_SPEED": 0x10000,
62+
"IN_JOYAUTOSPRINT": 0x20000,
63+
64+
}'''
65+

PyPlugins/tests/TestPlayerJump.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,33 @@ def OnPlayerJump(self,
7979

8080
alog("START")
8181
try:
82-
player = ADVPlayer(_slot)
8382
self.players_in_air[_slot] = True
84-
alog(player.GetName() + " jumped!")
83+
player = ADVPlayer(_slot)
84+
name = player.GetName()
85+
if (name):
86+
alog(name + " jumped!")
87+
else:
88+
alog("player.GetName() returned nullptr (jumped!)")
89+
except Exception as e:
90+
alog(e)
91+
alog(traceback.format_exc())
92+
alog("END")
93+
pass
94+
def OnClientDisconnect(self,
95+
_slot: int,
96+
_reason: int,
97+
_name: str,
98+
_xuid: int,
99+
_networkID: str):
100+
alog("START")
101+
try:
102+
alog("slot: " + str(_slot))
103+
alog("reason: " + str(_reason))
104+
alog(_name + " disconnected")
105+
alog("xuid: " + str(_xuid))
106+
alog("networkID: " + str(_networkID))
107+
self.last_grounded.pop(_slot, None)
108+
self.players_in_air.pop(_slot, None)
85109
except Exception as e:
86110
alog(e)
87111
alog(traceback.format_exc())
@@ -97,7 +121,12 @@ def OnPlayerLand(self,
97121
try:
98122
alog("_slot: " + str(_slot))
99123
player = ADVPlayer(_slot)
100-
alog(player.GetName() + " landed!")
124+
name = player.GetName()
125+
if (name):
126+
alog(name + " landed!")
127+
else:
128+
alog("player.GetName() returned nullptr (landed!)")
129+
101130
except Exception as e:
102131
alog(e)
103132
alog(traceback.format_exc())
@@ -113,7 +142,11 @@ def OnPlayerAirborn(self,
113142
try:
114143
alog("_slot: " + str(_slot))
115144
player = ADVPlayer(_slot)
116-
alog(player.GetName() + " is airborn!")
145+
name = player.GetName()
146+
if (name):
147+
alog(name + " is airborn!")
148+
else:
149+
alog("player.GetName() returned nullptr (is airborn!)")
117150
except Exception as e:
118151
alog(e)
119152
alog(traceback.format_exc())

cfg/cs2fixes/cs2fixes.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ cs2f_idle_kick_min_players 0 // Minimum amount of connected clients to kick id
137137
cs2f_idle_kick_admins 1 // Whether to kick idle players with ADMFLAG_GENERIC
138138
139139
// Button watch
140-
cs2f_enable_button_watch 0 // INCOMPATIBLE WITH CS#. Whether to enable button watch or not.
140+
cs2f_enable_button_watch 1 // INCOMPATIBLE WITH CS#. Whether to enable button watch or not.
141141
142142
// EntWatch Settings
143143
entwatch_enable 0 // INCOMPATIBLE WITH CS#. Whether to enable EntWatch features

src/PyModule.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ PYBIND11_EMBEDDED_MODULE(Source2Py, m) {
134134
.def("GetIndex", &ADVAPI::GetIndex)
135135
.def("IsOnGround", &ADVAPI::IsOnGround)
136136
.def("IsOnLadder", &ADVAPI::IsOnLadder)
137+
.def("GetButtons", &ADVAPI::GetButtons)
137138
.def("test",
138139
[](ADVAPI& self) -> int
139140
//Tristen, don't delete this, you'll eventually forget again.
@@ -142,6 +143,8 @@ PYBIND11_EMBEDDED_MODULE(Source2Py, m) {
142143
})
143144
;
144145
}
146+
147+
145148
m.def("CreateFakeEvent",
146149
[](const char* name, bool bForce) -> IGameEvent*
147150
{

src/adventuremod.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,26 @@ bool ADVAPI::IsValid()
3838
bool ADVAPI::IsOnGround()
3939
{
4040
CBaseEntity* ent = (CBaseEntity*)GetPawn();
41-
return ent->m_fFlags() & FL_ONGROUND;
41+
if (ent)
42+
return ent->m_fFlags() & FL_ONGROUND;
43+
return false;
4244
}
4345

4446
bool ADVAPI::IsOnLadder()
4547
{
4648
CBaseEntity* ent = (CBaseEntity*)GetPawn();
47-
return ent->m_MoveType() & MOVETYPE_LADDER;
49+
if (ent)
50+
return ent->m_MoveType() & MOVETYPE_LADDER;
51+
return false;
4852
}
53+
54+
uint64* ADVAPI::GetButtons()
55+
{
56+
CBaseEntity* pawn = (CBaseEntity*)GetPawn();
57+
CCSPlayerPawnBase* base = (CCSPlayerPawnBase*)pawn;
58+
CPlayer_MovementServices* ms = base->m_pMovementServices();
59+
// m_pButtonStates[0] is the mask of currently pressed buttons
60+
// m_pButtonStates[1] is the mask of buttons that changed in the current frame
61+
uint64* temp = ms->m_nButtons().m_pButtonStates();
62+
return temp;
63+
}

src/adventuremod.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ class ADVAPI
2323
CBaseEntity* GetPawn()
2424
{
2525
CCSPlayerController* pc = GetPC();
26-
return (CBaseEntity*)pc->GetPawn();
26+
if (pc)
27+
return (CBaseEntity*)pc->GetPawn();
28+
else
29+
return nullptr;
2730
}
2831

2932
int GetHealth();
@@ -32,7 +35,7 @@ class ADVAPI
3235
bool IsValid();
3336
bool IsOnGround();
3437
bool IsOnLadder();
35-
38+
uint64* GetButtons();
3639

3740

3841

0 commit comments

Comments
 (0)