FDS Crash [message #484487] |
Mon, 18 November 2013 15:12 |
Neijwiert
Messages: 124 Registered: October 2009
Karma: 0
|
Recruit |
|
|
Order of Crash:
- Join game
- Purchase refill
- Crash
Crash Type: Access violation
Crash points to: Scripts.dll
I know that it must have been my code, but I really can't find it. This is the code that I have that should get executed on refill:
// Not sure if it executes OnObjectCreate, but just in case
void NTC::OnObjectCreate(void *data, GameObject *obj)
{
Console_Output("A");
NTCPC->OnObjectCreate(obj);
}
bool NTC::OnRefill(GameObject *purchaser)
{
Console_Output("Refill\n");
return true;
}
It doesn't hit either of the Console_Output lines.
I'm out of ideas, can you please help me? I'm willing to hand over the complete source code I use.
I tried:
- Debug Text
- Attaching debugger
- Looking in the crashdump
[Updated on: Mon, 18 November 2013 15:13] Report message to a moderator
|
|
|
Re: FDS Crash [message #484488 is a reply to message #484487] |
Mon, 18 November 2013 15:32 |
Neijwiert
Messages: 124 Registered: October 2009
Karma: 0
|
Recruit |
|
|
After some more digging I found out that the problem lays at this method:
void NTCPlayerControl::Remove_Excess_Scripts(GameObject *Obj)
{
if(!Obj)
return;
// Loop trough all the scripts
SimpleDynVecClass<GameObjObserverClass *> Observers = Obj->Get_Observers();
int Count = Observers.Count();
for(int x = 0; x < Count; x++)
{
GameObjObserverClass *Current = Observers[x];
if(Current)
{
WideStringClass Name = Current->Get_Name();
if(Name.Compare(L"M00_GrantPowerup_Created") == 0 || Name.Substring(0, 4).Compare_No_Case(L"SSGM") == 0)
{
COutput("Should remove: %s\n", Current->Get_Name());
//Obj->Remove_Observer(Current);
}
}
}
}
As soon as I add the Obj->Remove_Observer line it starts crashing again. But I still haven't figured out why I cant add that line.
UPDATE:
I think somewhere in Scripts.dll there is code that assumes that all SSGM scripts are still attached.
I've changed the code to this to make sure the comparing is going right:
if(Current)
{
const char *ScriptName = Current->Get_Name();
//Name.Substring(0, 4).Compare_No_Case(L"SSGM") == 0
if(strcmp(ScriptName, "M00_GrantPowerup_Created") == 0 || (ScriptName && strlen(ScriptName) >= 4 && ScriptName[0] == 'S' && ScriptName[1] == 'S' && ScriptName[2] == 'G' && ScriptName[3] == 'M'))
{
COutput("Should remove: %s\n", Current->Get_Name());
Obj->Remove_Observer(Current);
}
}
[Updated on: Mon, 18 November 2013 15:42] Report message to a moderator
|
|
|
Re: FDS Crash [message #484489 is a reply to message #484487] |
Mon, 18 November 2013 15:52 |
Neijwiert
Messages: 124 Registered: October 2009
Karma: 0
|
Recruit |
|
|
As soon as I wrote this part "I think somewhere in Scripts.dll there is code that assumes that all SSGM scripts are still attached." and ate a cookie. I realised that it must have been in the SSGM code.
The one who is responsible of SSGM should change these 2 functions:
Toggle Spoiler
bool SSGMGameManager::RefillHook(GameObject *purchaser)
{
SSGM_Soldier *script = (SSGM_Soldier *)Find_Script_On_Object(purchaser,"SSGM_Soldier");
if (RefillLimit)
{
if (The_Game()->Get_Game_Duration_S() - script->RefillTime < RefillLimit)
{
return false;
}
}
script->RefillTime = The_Game()->Get_Game_Duration_S();
for (int i = 0;i < RegisteredEvents[EVENT_REFILL_HOOK].Count();i++)
{
if (!RegisteredEvents[EVENT_REFILL_HOOK][i]->OnRefill(purchaser))
{
return false;
}
}
return true;
}
int SSGMGameManager::CharacterPurchaseHook(BaseControllerClass *base,GameObject *purchaser,unsigned int cost,unsigned int preset,const char *data)
{
SSGM_Soldier *script = (SSGM_Soldier *)Find_Script_On_Object(purchaser,"SSGM_Soldier");
if (RefillLimit)
{
if (The_Game()->Get_Game_Duration_S() - script->RefillTime < RefillLimit)
{
return 4;
}
}
if (IsPresetDisabled(preset))
{
return 4;
}
StringClass str;
const char *str2 = Get_Translated_Definition_Name_Ini(Get_Definition_Name(preset));
const char *str3 = Get_Player_Name(purchaser);
str.Format("Purchase: %s - %s",str3,str2);
delete[] str3;
delete[] str2;
SSGMGameLog::Log_Message(str,"_PURCHASE");
bool fp = FreePurchases;
for (int i = 0;i < RegisteredEvents[EVENT_CHARACTER_PURCHASE_HOOK].Count();i++)
{
int ret = RegisteredEvents[EVENT_CHARACTER_PURCHASE_HOOK][i]->OnCharacterPurchase(base,purchaser,cost,preset,data);
if (ret == -2)
{
fp = true;
}
else if (ret != -1)
{
return ret;
}
}
if (fp)
{
return -2;
}
return -1;
}
to:
Toggle Spoiler
bool SSGMGameManager::RefillHook(GameObject *purchaser)
{
SSGM_Soldier *script = (SSGM_Soldier *)Find_Script_On_Object(purchaser,"SSGM_Soldier");
if(script)
{
if (RefillLimit)
{
if (The_Game()->Get_Game_Duration_S() - script->RefillTime < RefillLimit)
{
return false;
}
}
script->RefillTime = The_Game()->Get_Game_Duration_S();
for (int i = 0;i < RegisteredEvents[EVENT_REFILL_HOOK].Count();i++)
{
if (!RegisteredEvents[EVENT_REFILL_HOOK][i]->OnRefill(purchaser))
{
return false;
}
}
}
return true;
}
int SSGMGameManager::CharacterPurchaseHook(BaseControllerClass *base,GameObject *purchaser,unsigned int cost,unsigned int preset,const char *data)
{
SSGM_Soldier *script = (SSGM_Soldier *)Find_Script_On_Object(purchaser,"SSGM_Soldier");
if(script)
{
if (RefillLimit)
{
if (The_Game()->Get_Game_Duration_S() - script->RefillTime < RefillLimit)
{
return 4;
}
}
if (IsPresetDisabled(preset))
{
return 4;
}
StringClass str;
const char *str2 = Get_Translated_Definition_Name_Ini(Get_Definition_Name(preset));
const char *str3 = Get_Player_Name(purchaser);
str.Format("Purchase: %s - %s",str3,str2);
delete[] str3;
delete[] str2;
SSGMGameLog::Log_Message(str,"_PURCHASE");
bool fp = FreePurchases;
for (int i = 0;i < RegisteredEvents[EVENT_CHARACTER_PURCHASE_HOOK].Count();i++)
{
int ret = RegisteredEvents[EVENT_CHARACTER_PURCHASE_HOOK][i]->OnCharacterPurchase(base,purchaser,cost,preset,data);
if (ret == -2)
{
fp = true;
}
else if (ret != -1)
{
return ret;
}
}
if (fp)
{
return -2;
}
}
return -1;
}
[Updated on: Mon, 18 November 2013 15:54] Report message to a moderator
|
|
|
|
Re: FDS Crash [message #484493 is a reply to message #484487] |
Tue, 19 November 2013 06:36 |
Troll King
Messages: 56 Registered: June 2012 Location: Netherlands
Karma: 0
|
Recruit |
|
|
Oh right, hehe yeah sorry I wasn't really looking at it very well. I guess I was tired. But I think you get the suggestion that there needs to be a null pointer check.
Also Known As: Neijwiert
|
|
|
Re: FDS Crash [message #484496 is a reply to message #484487] |
Tue, 19 November 2013 10:43 |
|
danpaul88
Messages: 5795 Registered: June 2004 Location: England
Karma: 0
|
General (5 Stars) |
|
|
Revision: 6096
Author: danpaul88
Date: 19 November 2013 17:42:18
Message:
Added some null pointers check in the SSGM refill logic to guard against the SSGM_Soldier script somehow being removed from a soldier (ie: by third party code trying to override SSGM functionality with its own)
----
Modified : /trunk/scripts/scripts/gmgame.cpp
|
|
|