I think I've figured out the problem
It's a very oblique and weird error.
Just after I made my last post I added some debug printouts to the top of teh visibility processes code to figure out what's going on.
Logged in and it worked perfectly so i carried on making a few mods to streamline the same visibility processes, testing at each point.
Got monsters working with a single vector using push_back and erase.
In order to use erase though I had to know the iterator value and since the function was calling a Boolean to see if the present monster is in the list or not, I had to actually run the search locally to get that value. Either that or change the IsVisible functions to return an integer instead of true/false and that seems like a ton of work since those things get called all over the place.
So.... Still working after all the monsters are done.
Repeated the process on the NPCs and it still worked.
Found one tiny bug. I wasn't correctly using the erase command when moving out of visibility range of an NPC.
Fixed that and at teh same time took out the debug print code (cuz i didn't need it any more)
CRASH but not the same heap error.
This time every variable being accessed in the visibility processes is simply not there. It's like they haven't been assigned yet
Every variable associated with the visibility process is like that no matter how far i follow the stack down.
The root source of the function call is in the main Visibilty Process.
- // Visibility Process
- PVOID VisibilityProcess(PVOID TS)
- {
- while(GServer->ServerOnline)
- {
- pthread_mutex_lock( &GServer->PlayerMutex );
- pthread_mutex_lock( &GServer->MapMutex );
- for(UINT i=0;i<GServer->MapList.Map.size();i++)
- {
- CMap* map = GServer->MapList.Map.at(i);
- if( map->PlayerList.size()<1 )
- continue;
- for(UINT j=0;j<map->PlayerList.size();j++)
- {
- CPlayer* player = map->PlayerList.at(j);
- if(!player->Session->inGame)
- {
- continue;
- }
- if(!player->VisiblityList()) Log(MSG_WARNING, "Visibility False: %u", player->clientid );
- if( GServer->Config.AUTOSAVE == 1 )
- {
- clock_t etime = clock() - player->lastSaveTime;
- if( etime >= GServer->Config.SAVETIME*1000 )
- {
- player->savedata();
- player->lastSaveTime = clock();
- }
- }
- }
- }
- pthread_mutex_unlock( &GServer->MapMutex );
- pthread_mutex_unlock( &GServer->PlayerMutex );
- #ifdef _WIN32
- Sleep(GServer->Config.VisualDelay);
- #else
- usleep(GServer->Config.VisualDelay);
- #endif
- }
- pthread_exit(NULL);
- return 0;
- }
It's unable to run the player->VisiblityList() function because there's simply nothing there yet as far as I can tell.
As it's in a completely different thread I'm wondering if it's trying to run the visibility code before the player structure is being completely set up
Does that sound feasible?
I've never come across this before.
ABE
Nope that's not it.
Added a 100 loop delay timer before it was allowed to call visibilty. Loaded up fine but died the first time it called visibility.
This is starting to get on my nerves.
First it works then it doesn't then it does again and then just when I think I'm winning it fails again.
Update
Some more digging shows that it's not the first time it tries to touch the visibility lists any more.
It's successfully scanning through 184 of 185 monsters in
map->MonsterList as it tries to enter the final iteration it dies and doesn't even show me that line of code that's at fault. I figured this out by adding log messages.
I could try
- for(UINT i=0;i<map->MonsterList.size()-1;i++)
but that seems a bit retarded and would potentially leave a single monster on each map that nobody could ever see
Duh.... I'm being dumb here. The size of a vector is always one bigger than the index value of the last element
So that means it's clearing the monster list completely while debug log messages are present