Raised This Month: $ Target: $400
 0% 

A quick look?


  
 
 
Thread Tools Display Modes
Prev Previous Post   Next Post Next
Author Message
Nimgoble
Junior Member
Join Date: Apr 2006
Old 08-30-2008 , 10:44   A quick look?
Reply With Quote #1

Hello again. I was wondering if anyone would take a quick look at a couple of pieces of code of mine and tell me if they see anything wrong. There is something in this code that is crashing the server after about 20 minutes or so. It could be random, though I don't think it is. It always happens when the crossbow is being fired.

Code:
void ss_player::AdjustCrossbowFireRate()
{
	META_LOG(g_PLAPI, "Player %i Adjusting Crossbow Fire Rate", ss_index );

	if( playerinfomanager != NULL && pPlayer != NULL )
	{
		float time = playerinfomanager->GetGlobalVars()->curtime;

		//AMMO_OFFSET is an array that goes from 1576 to 1704.  The difference is 128.
		//The upper bounds of the ammo array is MAX_AMMO, which is 32. 128 / 32 = 4
		//The size of each ammo counter is 4 bytes.  So the ammo array is:
		//0:					1576 - 1579
		//AMMO_AR2:				1580 - 1583
		//AMMO_AR2_ALT:			1584 - 1587
		//AMMO_PISTOL:			1588 - 1591
		//AMMO_SMG1:			1592 - 1595
		//AMMO_357:				1596 - 1599
		//AMMO_CROSSBOW:		1600 - 1603
		//AMMO_SHOTGUN:			1604 - 1607
		//AMMO_RPG:				1608 - 1611
		//AAMMO_SMG1GREN:		1612 - 1615
		//AMMO_FRAG:			1616 - 1619
		//AMMO_SLAM:			1620 - 1623
		//So, my original calculation: AMMO_OFFSET + (AMMOO_CROSSBOW * ) = 
		//1576 + (6 * 4) = 1576 + 24 = 1600, which is the crossbow.  Shit.  I WAS correct...So why is it crashing?

		datamap_t *pMap = pPlayer->GetDataDescMap();
		int AMMO_OFFSET = GetOffset( pMap, "m_iAmmo" );

		
		if( AMMO_OFFSET > 0 )
		{
			//Is this right?  Setting the crossbow ammo pointer to one less....memory address?
			*(int *)((char *)pPlayer + (AMMO_OFFSET + (AMMO_CROSSBOW * 4 ))) = *(int *)((char * )pPlayer + (AMMO_OFFSET + (AMMO_CROSSBOW * 4 ))) - 1;
		}
		UpdateCrossbow();
	}
}
The part where I set the ammo is my guess on what's going wrong. I don't know if that's the correct way to do it.

Here is the UpdateCrossbow and UpdateActiveWeapon, just in case.

Code:
void ss_player::UpdateCrossbow()
{
	META_LOG(g_PLAPI, "Player %i Begin Update Crossbow", ss_index );

	//Make sure we have the crossbow.
	if( pCrossbow )
	{
		//time.  Used to set the next fire time of the player and crossbow
		float time = 0;

		//Make sure playerinfomanager isn't null.
		if( playerinfomanager != NULL )
			playerinfomanager->GetGlobalVars()->curtime + ss_crossbow_refire.GetFloat();
		else
			return;
		
		//Our data maps.  Used to find the offsets of data members
		datamap_t *pPlayerMap, *pCrossbowMap, *pCombatCharMap;

		//Continuing without these would be pointless and stupid.
		if( pPlayer == NULL ||
			pCrossbow == NULL ||
			pCombatChar == NULL )
			return;

		pPlayerMap = pPlayer->GetDataDescMap();
		pCrossbowMap = pCrossbow->GetDataDescMap();
		pCombatCharMap = pCombatChar->GetDataDescMap();

		//Don't mess with anything if we don't have ALL of our datamaps.
		if( pPlayerMap == NULL ||
			pCrossbowMap == NULL ||
			pCombatCharMap == NULL )
			return;

		//The individual data member offsets.
		int AMMO_OFFSET, CLIP1_OFFSET, IDLE_TIME_OFFSET, NEXT_PRIMARY_ATTACK_OFFSET, NEXT_ATTACK_OFFSET, IN_RELOAD_OFFSET;

		//Player
		AMMO_OFFSET = GetOffset( pPlayerMap, "m_iAmmo" );

		//Crossbow
		CLIP1_OFFSET = GetOffset( pCrossbowMap, "m_iClip1" ); 
		IDLE_TIME_OFFSET = GetOffset( pCrossbowMap, "m_flTimeWeaponIdle" );
		NEXT_PRIMARY_ATTACK_OFFSET = GetOffset( pCrossbowMap, "m_flNextPrimaryAttack" );
		IN_RELOAD_OFFSET = GetOffset( pCrossbowMap, "m_bInReload" );

		//CombatChar
		NEXT_ATTACK_OFFSET = GetOffset( pCombatCharMap, "m_flNextAttack" );

		//Don't give more ammo when we run out.
		if( *(int *)((char * )pPlayer + (AMMO_OFFSET + (AMMO_CROSSBOW * 4 ))) <= 0 )
		{
			META_LOG(g_PLAPI, "End UpdateCrossbow() with no ammo. player: %i", ss_index);
			return;
		}

		//RELOAD.  FAST
		if( *(int *)((char*)pCrossbow + CLIP1_OFFSET) <= 0 )
		{
			*(int *)((char*)pCrossbow + CLIP1_OFFSET) = 1;
		}
		//IDLE TIME = time
		*(float *)((char *)pCrossbow + IDLE_TIME_OFFSET) = time;
		//NEXT ATTACK TIME = NOW
		*(float *)((char *)pCrossbow + NEXT_PRIMARY_ATTACK_OFFSET) = time;

		//NEXT PLAYER ATTACK TIME = NOW
		if( pCombatChar != NULL )
			*(float *)((char *)pCombatChar + NEXT_ATTACK_OFFSET) = time;

		//Don't need a reload.
		*(bool *)((char *)pCrossbow + IN_RELOAD_OFFSET) = false;
	}
	META_LOG(g_PLAPI, "Player %i End Update Crossbow", ss_index );
}
Too make sure that nothing was going wrong in there, I went back and checked to see if everything was instantiated. I think I dotted every "i" and crossed every "t", but sometimes you miss things like that.

Here is the ActiveWeapon code.

Code:
void ss_player::UpdateActiveWeapon()
{
	META_LOG(g_PLAPI, "Player %i Begin Active Weapon Update", ss_index );
	datamap_t *pCombatCharMap = NULL;
	int ACTIVE_OFFSET = 0;
	CBaseHandle *pHandle = NULL;

	if( pCombatChar != NULL )
	{
		pCombatCharMap = pCombatChar->GetDataDescMap();
		if( pCombatCharMap != NULL )
		{
			ACTIVE_OFFSET = GetOffset( pCombatCharMap, "m_hActiveWeapon" );
			pHandle = (CBaseHandle *)((char *)pCombatChar + ACTIVE_OFFSET);
		}
	}

	if( pHandle != NULL && m_Engine != NULL )
	{
		edict_t *pEdict = m_Engine->PEntityOfEntIndex(pHandle->GetEntryIndex());
		if( pEdict != NULL )
		{
			CBaseEntity *pEnt = pEdict->GetIServerEntity()->GetBaseEntity();
			if( pEnt  != NULL )
			{
				pActive = (CBaseCombatWeapon*)pEnt;
				if( pActive != NULL)
				{
					/* If our active weapon is not equal to our shotgun pointer: unhook the shotgun.
						we don't need it hooked if it isn't active.  Then check to see if our active weapon IS
						a shotgun.  If so, hook it.
					*/
					if( pActive != pShotgun )
					{
						if(pShotgun != NULL )
						{
							UnHookShotgun();
						}
						
						if( (stricmp(pActive->GetClassname(), "weapon_shotgun") == 0 ) )
						{	
							pShotgun = pActive;
							HookShotgun();
						}
					}
					if( pActive != pCrossbow )
					{
						if( pCrossbow != NULL )
						{
							UnHookCrossbow();
						}
						
						if( (stricmp(pActive->GetClassname(), "weapon_crossbow") == 0) )
						{
							pCrossbow = pActive;
							if( pCombatChar != NULL )
							{
								datamap_t *pMap = pCombatChar->GetDataDescMap();
								if( pMap != NULL )
								{
									int AMMO_OFFSET = GetOffset( pMap, "m_iAmmo" );
									//We have a new crossbow, time to fill up the ammo.
									*(int *)((char *)pCombatChar + (AMMO_OFFSET + (AMMO_CROSSBOW * 4))) = ss_crossbow_ammo.GetInt();

								}
							}
							HookCrossbow();
						}
					}
				}
			}
		}
	}
	META_LOG(g_PLAPI, "Player %i End Active Weapon Update", ss_index );
}
The above code checks the current weapon and hooks it if necessary.

I've been banging my head against the keyboard for weeks trying to figure this out. I appreciate the help.
Nimgoble is offline
 



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


All times are GMT -4. The time now is 12:57.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode