Skip to content

Commit 09ca272

Browse files
authored
[GEN][ZH] Fix tunnel contain crashes due to uninitialized tunnel systems (#1310)
1 parent 096dd0e commit 09ca272

File tree

4 files changed

+106
-9
lines changed

4 files changed

+106
-9
lines changed

Generals/Code/GameEngine/Include/GameLogic/Module/TunnelContain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,8 @@ class TunnelContain : public OpenContain, public CreateModuleInterface
9898
virtual void onRemoving( Object *obj ); ///< object no longer contains 'obj'
9999
virtual void onSelling();///< Container is being sold. Tunnel responds by kicking people out if this is the last tunnel.
100100

101+
virtual void orderAllPassengersToExit( CommandSourceType commandSource ); ///< All of the smarts of exiting are in the passenger's AIExit. removeAllFrommContain is a last ditch system call, this is the game Evacuate
102+
101103
virtual Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const;
102104
virtual void addToContainList( Object *obj ); ///< The part of AddToContain that inheritors can override (Can't do whole thing because of all the private stuff involved)
103105
virtual void removeFromContain( Object *obj, Bool exposeStealthUnits = FALSE ); ///< remove 'obj' from contain list

Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ TunnelContain::~TunnelContain()
6565
void TunnelContain::addToContainList( Object *obj )
6666
{
6767
Player *owningPlayer = getObject()->getControllingPlayer();
68+
69+
if(!owningPlayer->getTunnelSystem())
70+
return;
71+
6872
owningPlayer->getTunnelSystem()->addToContainList( obj );
6973
}
7074

@@ -97,6 +101,9 @@ void TunnelContain::removeFromContain( Object *obj, Bool exposeStealthUnits )
97101
if( owningPlayer == NULL )
98102
return; //game tear down. We do the onRemove* stuff first because this is allowed to fail but that still needs to be done
99103

104+
if(!owningPlayer->getTunnelSystem())
105+
return;
106+
100107
owningPlayer->getTunnelSystem()->removeFromContain( obj, exposeStealthUnits );
101108

102109
}
@@ -106,8 +113,12 @@ void TunnelContain::removeFromContain( Object *obj, Bool exposeStealthUnits )
106113
//-------------------------------------------------------------------------------------------------
107114
void TunnelContain::removeAllContained( Bool exposeStealthUnits )
108115
{
109-
ContainedItemsList list;
110116
Player *owningPlayer = getObject()->getControllingPlayer();
117+
118+
if(!owningPlayer->getTunnelSystem())
119+
return;
120+
121+
ContainedItemsList list;
111122
owningPlayer->getTunnelSystem()->swapContainedItemsList(list);
112123

113124
ContainedItemsList::iterator it = list.begin();
@@ -127,6 +138,10 @@ void TunnelContain::removeAllContained( Bool exposeStealthUnits )
127138
void TunnelContain::iterateContained( ContainIterateFunc func, void *userData, Bool reverse )
128139
{
129140
Player *owningPlayer = getObject()->getControllingPlayer();
141+
142+
if(!owningPlayer->getTunnelSystem())
143+
return;
144+
130145
owningPlayer->getTunnelSystem()->iterateContained( func, userData, reverse );
131146
}
132147

@@ -190,7 +205,11 @@ void TunnelContain::onSelling()
190205
Bool TunnelContain::isValidContainerFor(const Object* obj, Bool checkCapacity) const
191206
{
192207
Player *owningPlayer = getObject()->getControllingPlayer();
193-
return owningPlayer->getTunnelSystem()->isValidContainerFor( obj, checkCapacity );
208+
if( owningPlayer && owningPlayer->getTunnelSystem() )
209+
{
210+
return owningPlayer->getTunnelSystem()->isValidContainerFor( obj, checkCapacity );
211+
}
212+
return false;
194213
}
195214

196215
UnsignedInt TunnelContain::getContainCount() const
@@ -206,13 +225,21 @@ UnsignedInt TunnelContain::getContainCount() const
206225
Int TunnelContain::getContainMax( void ) const
207226
{
208227
Player *owningPlayer = getObject()->getControllingPlayer();
209-
return owningPlayer->getTunnelSystem()->getContainMax();
228+
if( owningPlayer && owningPlayer->getTunnelSystem() )
229+
{
230+
return owningPlayer->getTunnelSystem()->getContainMax();
231+
}
232+
return 0;
210233
}
211234

212235
const ContainedItemsList* TunnelContain::getContainedItemsList() const
213236
{
214237
Player *owningPlayer = getObject()->getControllingPlayer();
215-
return owningPlayer->getTunnelSystem()->getContainedItemsList();
238+
if( owningPlayer && owningPlayer->getTunnelSystem() )
239+
{
240+
return owningPlayer->getTunnelSystem()->getContainedItemsList();
241+
}
242+
return NULL;
216243
}
217244

218245

@@ -339,6 +366,16 @@ void TunnelContain::onBuildComplete( void )
339366
m_isCurrentlyRegistered = TRUE;
340367
}
341368

369+
//-------------------------------------------------------------------------------------------------
370+
void TunnelContain::orderAllPassengersToExit( CommandSourceType commandSource )
371+
{
372+
Player *owningPlayer = getObject()->getControllingPlayer();
373+
if( !owningPlayer || !owningPlayer->getTunnelSystem() )
374+
return;
375+
376+
OpenContain::orderAllPassengersToExit( commandSource );
377+
}
378+
342379
// ------------------------------------------------------------------------------------------------
343380
/** Per frame update */
344381
// ------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/TunnelContain.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ class TunnelContain : public OpenContain, public CreateModuleInterface
102102
virtual void onSelling();///< Container is being sold. Tunnel responds by kicking people out if this is the last tunnel.
103103
virtual void onCapture( Player *oldOwner, Player *newOwner ); // Need to change who we are registered with.
104104

105+
virtual void orderAllPassengersToExit( CommandSourceType commandSource, Bool instantly ); ///< All of the smarts of exiting are in the passenger's AIExit. removeAllFrommContain is a last ditch system call, this is the game Evacuate
106+
virtual void orderAllPassengersToIdle( CommandSourceType commandSource ); ///< Just like it sounds
107+
105108
virtual Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const;
106109
virtual void addToContainList( Object *obj ); ///< The part of AddToContain that inheritors can override (Can't do whole thing because of all the private stuff involved)
107110
virtual void removeFromContain( Object *obj, Bool exposeStealthUnits = FALSE ); ///< remove 'obj' from contain list

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ TunnelContain::~TunnelContain()
6565
void TunnelContain::addToContainList( Object *obj )
6666
{
6767
Player *owningPlayer = getObject()->getControllingPlayer();
68+
69+
if(!owningPlayer->getTunnelSystem())
70+
return;
71+
6872
owningPlayer->getTunnelSystem()->addToContainList( obj );
6973
}
7074

@@ -97,6 +101,9 @@ void TunnelContain::removeFromContain( Object *obj, Bool exposeStealthUnits )
97101
if( owningPlayer == NULL )
98102
return; //game tear down. We do the onRemove* stuff first because this is allowed to fail but that still needs to be done
99103

104+
if(!owningPlayer->getTunnelSystem())
105+
return;
106+
100107
owningPlayer->getTunnelSystem()->removeFromContain( obj, exposeStealthUnits );
101108

102109
}
@@ -109,6 +116,10 @@ void TunnelContain::removeFromContain( Object *obj, Bool exposeStealthUnits )
109116
void TunnelContain::harmAndForceExitAllContained( DamageInfo *info )
110117
{
111118
Player *owningPlayer = getObject()->getControllingPlayer();
119+
120+
if(!owningPlayer->getTunnelSystem())
121+
return;
122+
112123
const ContainedItemsList *fullList = owningPlayer->getTunnelSystem()->getContainedItemsList();
113124

114125
Object *obj;
@@ -146,8 +157,12 @@ void TunnelContain::killAllContained( void )
146157
// on the death of the host container. This is reproducible by shooting with
147158
// Neutron Shells on a GLA Tunnel containing GLA Terrorists.
148159

149-
ContainedItemsList list;
150160
Player *owningPlayer = getObject()->getControllingPlayer();
161+
162+
if(!owningPlayer->getTunnelSystem())
163+
return;
164+
165+
ContainedItemsList list;
151166
owningPlayer->getTunnelSystem()->swapContainedItemsList(list);
152167

153168
ContainedItemsList::iterator it = list.begin();
@@ -167,8 +182,12 @@ void TunnelContain::killAllContained( void )
167182
//-------------------------------------------------------------------------------------------------
168183
void TunnelContain::removeAllContained( Bool exposeStealthUnits )
169184
{
170-
ContainedItemsList list;
171185
Player *owningPlayer = getObject()->getControllingPlayer();
186+
187+
if(!owningPlayer->getTunnelSystem())
188+
return;
189+
190+
ContainedItemsList list;
172191
owningPlayer->getTunnelSystem()->swapContainedItemsList(list);
173192

174193
ContainedItemsList::iterator it = list.begin();
@@ -188,6 +207,10 @@ void TunnelContain::removeAllContained( Bool exposeStealthUnits )
188207
void TunnelContain::iterateContained( ContainIterateFunc func, void *userData, Bool reverse )
189208
{
190209
Player *owningPlayer = getObject()->getControllingPlayer();
210+
211+
if(!owningPlayer->getTunnelSystem())
212+
return;
213+
191214
owningPlayer->getTunnelSystem()->iterateContained( func, userData, reverse );
192215
}
193216

@@ -261,7 +284,11 @@ void TunnelContain::onSelling()
261284
Bool TunnelContain::isValidContainerFor(const Object* obj, Bool checkCapacity) const
262285
{
263286
Player *owningPlayer = getObject()->getControllingPlayer();
264-
return owningPlayer->getTunnelSystem()->isValidContainerFor( obj, checkCapacity );
287+
if( owningPlayer && owningPlayer->getTunnelSystem() )
288+
{
289+
return owningPlayer->getTunnelSystem()->isValidContainerFor( obj, checkCapacity );
290+
}
291+
return false;
265292
}
266293

267294
UnsignedInt TunnelContain::getContainCount() const
@@ -277,13 +304,21 @@ UnsignedInt TunnelContain::getContainCount() const
277304
Int TunnelContain::getContainMax( void ) const
278305
{
279306
Player *owningPlayer = getObject()->getControllingPlayer();
280-
return owningPlayer->getTunnelSystem()->getContainMax();
307+
if( owningPlayer && owningPlayer->getTunnelSystem() )
308+
{
309+
return owningPlayer->getTunnelSystem()->getContainMax();
310+
}
311+
return 0;
281312
}
282313

283314
const ContainedItemsList* TunnelContain::getContainedItemsList() const
284315
{
285316
Player *owningPlayer = getObject()->getControllingPlayer();
286-
return owningPlayer->getTunnelSystem()->getContainedItemsList();
317+
if( owningPlayer && owningPlayer->getTunnelSystem() )
318+
{
319+
return owningPlayer->getTunnelSystem()->getContainedItemsList();
320+
}
321+
return NULL;
287322
}
288323

289324

@@ -459,6 +494,26 @@ void TunnelContain::onCapture( Player *oldOwner, Player *newOwner )
459494
OpenContain::onCapture( oldOwner, newOwner );
460495
}
461496

497+
//-------------------------------------------------------------------------------------------------
498+
void TunnelContain::orderAllPassengersToExit( CommandSourceType commandSource, Bool instantly )
499+
{
500+
Player *owningPlayer = getObject()->getControllingPlayer();
501+
if( !owningPlayer || !owningPlayer->getTunnelSystem() )
502+
return;
503+
504+
OpenContain::orderAllPassengersToExit( commandSource, instantly );
505+
}
506+
507+
//-------------------------------------------------------------------------------------------------
508+
void TunnelContain::orderAllPassengersToIdle( CommandSourceType commandSource )
509+
{
510+
Player *owningPlayer = getObject()->getControllingPlayer();
511+
if( !owningPlayer || !owningPlayer->getTunnelSystem() )
512+
return;
513+
514+
OpenContain::orderAllPassengersToIdle( commandSource );
515+
}
516+
462517
// ------------------------------------------------------------------------------------------------
463518
/** Per frame update */
464519
// ------------------------------------------------------------------------------------------------

0 commit comments

Comments
 (0)