.:: Bots United ::.  
filebase forums discord server github wiki web
cubebot epodbot fritzbot gravebot grogbot hpbbot ivpbot jkbotti joebot
meanmod podbotmm racc rcbot realbot sandbot shrikebot soulfathermaps yapb

Go Back   .:: Bots United ::. > Developer's Farm > General Bot Coding
General Bot Coding See what a pain it is to get those little mechs shooting around

Reply
 
Thread Tools
SWDS.dll Crashes.
Old
  (#1)
voogru
Guest
 
Status:
Posts: n/a
Default SWDS.dll Crashes. - 17-08-2004

Hello,

I've been using a system which spawns entities similar to the way they are done in botmans monster plug-in, but rather than using a func_wall, I'm using an info_target.

I've been using this code for a while and have noticed frequent crashes from swds.dll when its in a state where players can make entities (now, the ents are limited so players cant just go making 10 million of them).

Unfortunately, I know that its something with the entities causing the crash, but with no call stack or not even a clue on to what’s crashing it, I really don’t have an idea what’s doing it (Call stack just shows !SWDS 0xWhatever)


Code:
template <class T> T * NSAGetClassPtr( T *a)
{
edict_t *pEnt = (edict_t *)a;
 
// allocate entity if necessary
if (pEnt == NULL) 
{
pEnt = CREATE_NAMED_ENTITY(MAKE_STRING("info_target"));
if(!UTIL_IsValidEntity(pEnt))
return NULL;
DispatchSpawn( pEnt );
}
// get the private data
a = (T *)pEntityData[ENTINDEX(pEnt)];
 
if (a == NULL) 
{
a = new T;
if(pEntityData[ ENTINDEX( pEnt ) ])
{
UTIL_LogPrintf("WARNING: Found pointer for entity that doesnt exist!\n");
FREE_MEM(pEntityData[ ENTINDEX( pEnt ) ]);
}
pEntityData[ ENTINDEX( pEnt ) ] = a;
a->pev = VARS(pEnt);
}
return a;
}


Entities are removed using the pev->flags |= FL_KILLME, theres a loop in start frame running thru all the possible indexes checking for the flag to free the memory allocated for the entity. pEntityData is an array of 1380 pointers. (max entities with 32 players).

The wierd part is, changing CREATE_NAMED_ENTITY to CREATE_ENTITY made all the nasty crashes from SWDS.dll go away, but the mod will crash if I make the entity solid (The mod does a trace line, if the entity it hits isnt null, it tries to access a cbaseentity instance without checking if its null first).

Preferably, I'd like to keep using the create_named_entity command if anyone has an idea of why swds would be crashing.

Fyi, SWDS.dll is the dedicated server engine dll as far as I know.

Anyone have any ideas? Botman?

Thanks.
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#2)
Cheeseh
[rcbot]
 
Cheeseh's Avatar
 
Status: Offline
Posts: 361
Join Date: Dec 2003
Location: China
Default Re: SWDS.dll Crashes. - 18-08-2004

Im guessing that the engine is crashing because you are freeing the entities and the engines list of entities still has these dangling pointers to the entities that you freed.

Instead of "freeing" them, use pfnRemoveEntity in engine functions. (Thats same as REMOVE_ENTITY(edict_t*) ). That will allow the engine to do what it needs to ensure the edict you removed is not valid anymore.


Last edited by Cheeseh; 19-08-2004 at 00:01..
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#3)
voogru
Guest
 
Status:
Posts: n/a
Default Re: SWDS.dll Crashes. - 19-08-2004

Auctually thats how I've been removing them, using remove_entity most of the time, I switched to flags |= FL_KILLME as I figured it might have been a problem with the remove_entity function (and the fact I rarely seen it used in HLSDK)

The data that I free for the entity is a pointer to its class instance, which is all me. (ie, delete pEntityData[index] Once thats deleted the entity can still exist but will be nothing but an info_target.

The thing is it doesnt seem to crash all the time, I went ahead and started making thousands of entities overnight and it wouldnt crash (50 ents a second with 2 second lifetime).
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#4)
Cheeseh
[rcbot]
 
Cheeseh's Avatar
 
Status: Offline
Posts: 361
Join Date: Dec 2003
Location: China
Default Re: SWDS.dll Crashes. - 19-08-2004

Ok well I'm interested in solving your problem

thing I don't get is...

Code:
a = (T *)pEntityData[ENTINDEX(pEnt)];

if (a == NULL) 
{
a = new T;
if(pEntityData[ ENTINDEX( pEnt ) ])
{
if "a" is NULL then "(pEntityData[ ENTINDEX( pEnt ) ])" has got to be NULL (in the IF statement) so the IF statement is true... Yeah? Is it intended? in any case it will never free.

I never exactly had a good look at the monster plugin to see how entities were spawned, I'm guessing as you say, you are using similar code to that of it?

What exactly are you wanting to do (in the long run)? I'm sure there maybe an easier way to go about doing it.
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#5)
voogru
Guest
 
Status:
Posts: n/a
Default Re: SWDS.dll Crashes. - 19-08-2004

Hmm, thats right.


Duh...

Thanks for spotting that.

The purpose of this code is to make modifying entities & making new entities just like you would make an entity with the CBaseEntity class, only for server side mods as well.

The nice thing about it is it makes fooling around with existing entities (ie, the phasegate in NS) really simple.

That snippet I posted only creates an entity when creating a custom entity (ie, my nuke or fireworks ents).

Last edited by voogru; 19-08-2004 at 02:11..
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#6)
Cheeseh
[rcbot]
 
Cheeseh's Avatar
 
Status: Offline
Posts: 361
Join Date: Dec 2003
Location: China
Default Re: SWDS.dll Crashes. - 19-08-2004

theory:

If you are calling CBaseEntity methods through a pointer you got from your create function it could be accessing the wrong area of memory i.e. if you casted it wrong and called a method, the method locations will be in the wrong place and execution could wander through lines of code which manipulates the call stack and leaving it in an inconsistant state... (if by calling a method it took code into the middle of a function, it would not push the stack but would pop it at the end)

in short:

I'm guessing you are casting the values returned by your create function from edict_t* to CBaseEntity*

The thing I believe is that to cast an edict_t* to a CBaseEntity* you must cast it by it's privateData and not the edict_t* memory location. i.e. by:

CBaseEntity *pEnt = (CBaseEntity*)GET_PRIVATE(pEdict);

To help you, here is code from my "marine build" function from my bot, which I am also guessing you are using natural-selection. My code works okay when spawning structures in Natural-selection, even resource towers but they don't give resources to the marines (at least that doesn't crash though, i found why it crashes in that case)

have a look if you wish:

Code:
//
// Hack building
edict_t *BotFunc_NS_MarineBuild ( int iUser3, const char *szClassname, Vector vOrigin, edict_t *pEntityUser )
{
	edict_t *build = NULL;//pfnCreateNamedEntity(MAKE_STRING(pCommBuildent));

	edict_t *pSetgroundentity = NULL;


	if ( iUser3 == AVH_USER3_RESTOWER )
	{
		// find nearest struct resource fountain
		char *classname[1] = {"func_resource"};
		
		edict_t *pResource = UTIL_FindNearestEntity(classname,1,vOrigin,200,FALSE);
		
		if ( pResource )
		{
			if ( UTIL_IsResourceFountainUsed(pResource) )
			{
				BotMessage(pEntityUser,0,"Error: Nearest resource fountain is used");
				return NULL;
			}

			pSetgroundentity = pResource;
			vOrigin = pResource->v.origin+Vector(0,0,1);
		}
		else
		{
			BotMessage(pEntityUser,0,"Error: Can't find a resource fountain for tower");
			return NULL;
		}
	}

	build = CREATE_NAMED_ENTITY(MAKE_STRING(szClassname));
	
	if ( build && !FNullEnt(build) )
	{
		if ( pSetgroundentity )
			build->v.groundentity = pSetgroundentity;

		SET_ORIGIN(build,vOrigin);			
		
		build->v.iuser3 = iUser3;
		
		if ( iUser3 != AVH_USER3_MARINEITEM )			
		{
			build->v.iuser4 = MASK_BUILDABLE | MASK_SELECTABLE;
		}
		else
			build->v.iuser4 = MASK_NONE;
		
		build->v.takedamage = 1;
		build->v.movetype = 6;
		build->v.solid = 2;
		build->v.team = 1;
		build->v.flags = 544;
		
		build->v.nextthink = gpGlobals->time + 0.1;

#ifdef RCBOT_META_BUILD
		MDLL_Spawn(build);
#else
		DispatchSpawn(build);
#endif

		return build;
	}

	return NULL;
}
[/code]
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#7)
voogru
Guest
 
Status:
Posts: n/a
Default Re: SWDS.dll Crashes. - 19-08-2004

My code doesnt use anything relating to CBaseEntity, its totally independant.

Code:
CEBaseEntity *pEntityData[NSA_MAX_ENTS+1];


Code:
 static CEBaseEntity *Instance( edict_t *pent )
{ 
if (!pent || !pEntityData[ENTINDEX(pent)] )
return NULL;
return pEntityData[ENTINDEX(pent)]; 
}

pEntityData is basically the same as pvPrivateData.

Example class:

Code:
class CLight : public CEBaseEntity
{
private:
int m_iRadius;
Vector m_vecColor;
public:
void Spawn( void )
{
if(!GetOwner())
{
Remove();
return;
}
NSASetThink(&CLight::LightThink);
pev->nextthink = gpGlobals->time;
}
bool LightThink( void )
{
if(!UTIL_IsValidEntity( GetOwner() ))
{
Remove();
return false;
}
MESSAGE_BEGIN(MSG_BROADCAST, SVC_TEMPENTITY);
WRITE_BYTE( TE_DLIGHT );
WRITE_COORD(GetOwner()->v.origin.x); 
WRITE_COORD(GetOwner()->v.origin.y);
WRITE_COORD(GetOwner()->v.origin.z);
WRITE_BYTE(GetRadius()); //radius * 0.1
WRITE_BYTE(GetColor().x);
WRITE_BYTE(GetColor().y);
WRITE_BYTE(GetColor().z);
WRITE_BYTE( 30 );	 // life * 10
WRITE_BYTE( 0 ); // decay
MESSAGE_END();
pev->nextthink = gpGlobals->time + 3.0;
return false;
}
void SetColor( Vector vecColor) { m_vecColor = vecColor; }
Vector GetColor ( void ) { return m_vecColor; }
void SetRadius( int iRadius) { m_iRadius = iRadius; }
int GetRadius ( void ) { return m_iRadius; }
};
Example spawn code:

New entity:

Code:
CEBaseEntity *pFireWork = NSAGetClassPtr( (CFireWork *)NULL);
if(pFireWork) 
{
pFireWork->SetOwner(pEdict);
pFireWork->Spawn();
}
Hook Entity:

Code:
CEBaseEntity *pHive = NSAGetClassPtr( (CHive*)HiveEdict);
if(pHive) 
{
pHive->Spawn();
}

Last edited by voogru; 19-08-2004 at 03:19..
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#8)
sfx1999
Member
 
sfx1999's Avatar
 
Status: Offline
Posts: 534
Join Date: Jan 2004
Location: Pittsburgh, PA, USA
Default Re: SWDS.dll Crashes. - 20-08-2004

IIRC, Monster makes monsters like this:

Code:
CBaseEntity *whatever = new CMonsterBarney
I don't quite understand it myself. However, I don't think this would work for hives, as you need the class pointer.

So I am wondering, if you were to spawn, say a hive in NS, would you do it like this?

Code:
CBaseEntity *thenewhive = new getClassPtr("info_hive")
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#9)
Pierre-Marie Baty
Roi de France
 
Pierre-Marie Baty's Avatar
 
Status: Offline
Posts: 5,049
Join Date: Nov 2003
Location: 46°43'60N 0°43'0W 0.187A
Default Re: SWDS.dll Crashes. - 20-08-2004

A dumb question (don't hurt me) but, when using CREATE_ENTITY() and making the entity solid, wouldn't you forget to set a bounding box ?

How do you manipulate your entity once it's created ? (setting position, angle and BB)



RACC home - Bots-United: beer, babies & bots (especially the latter)
"Learn to think by yourself, else others will do it for you."
  
Reply With Quote
Re: SWDS.dll Crashes.
Old
  (#10)
voogru
Guest
 
Status:
Posts: n/a
Default Re: SWDS.dll Crashes. - 21-08-2004

CREATE_ENTITY() doesnt allocate a cbaseentity class for the entity, the mod then tries to access a cbaseentity pointer on solid ents if you look at it, without checking the pointer first.


All of the additional entity manipulation is performed in the spawn code, setting model, bbox, etc.
  
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump



Powered by vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
vBulletin Skin developed by: vBStyles.com