//---------------------------------------------------------------------------------
	// Purpose: returns the specified prop offset relative to the table provided.
	//			if offset or table not found, bErr returns true and offset returned is 0
	//---------------------------------------------------------------------------------
	unsigned int GetPropOffsetFromTable(const char *pTableName, const char *pPropName)
	{
		ServerClass *pClass = pServerDLL->GetAllServerClasses();
		if (!pClass)
		{
			Warning("servergamedll->GetAllServerClasses() returned null\n");
			return 0;
		}
		while (pClass)
		{
			SendTable *pTable = GetDataTable( pTableName, pClass->m_pTable );
			if (pTable == NULL)
			{
				pClass = pClass->m_pNext;
				continue;
			}
			int num = pTable->GetNumProps();
			for (int i = 0; i < num; i++)
			{
				SendProp *pProp = pTable->GetProp(i);
				if ( FStrEq( pPropName, pProp->GetName() ) )
				{
					return pProp->GetOffset();
				}
			}
			pClass = pClass->m_pNext;
		}
		Warning("prop %s not found in %s or table name incorrect\n", pPropName, pTableName);
		return 0;
	}
Example #2
0
bool UTIL_ContainsDataTable(SendTable *pTable, const char *name)
{
	const char *pname = pTable->GetName();
	int props = pTable->GetNumProps();
	SendProp *prop;
	SendTable *table;

	if (pname && strcmp(name, pname) == 0)
		return true;

	for (int i=0; i<props; i++)
	{
		prop = pTable->GetProp(i);

		if ((table = prop->GetDataTable()) != NULL)
		{
			pname = table->GetName();
			if (pname && strcmp(name, pname) == 0)
			{
				return true;
			}

			if (UTIL_ContainsDataTable(table, name))
			{
				return true;
			}
		}
	}

	return false;
}
	//---------------------------------------------------------------------------------
	// Purpose: returns the specified prop from the class and table provided.
	//			if prop or table not found, pointer returns NULL
	//---------------------------------------------------------------------------------
	SendProp *GetPropFromClassAndTable(const char *szClassName, const char *szTableName, const char *szPropName)
	{
		ServerClass *pServerClass = pServerDLL->GetAllServerClasses();
		if (!pServerClass)
		{
			Warning("servergamedll->GetAllServerClasses() returned null\n");
			return NULL;
		}
		while (pServerClass)
		{
			if ( FStrEq(szClassName, pServerClass->GetName()) )
			{
				SendTable *pTable = GetDataTable( szTableName, pServerClass->m_pTable );
				if (pTable)
				{
					int numprops = pTable->GetNumProps();
					for (int i = 0; i < numprops; ++i)
					{
						SendProp *pProp = pTable->GetProp(i);
						if (pProp && FStrEq(szPropName, pProp->GetName()) )
						{
							return pProp;
						}
					}
				}
			}
			pServerClass = pServerClass->m_pNext;
		}
		Warning("prop %s not found in %s => %s\n", szPropName, szClassName, szTableName);
		return NULL;
	}
void SendTable_PrintStats( void )
{
	int numTables = 0;
	int numFloats = 0;
	int numStrings = 0;
	int numArrays = 0;
	int numInts = 0;
	int numVecs = 0;
	int numSubTables = 0;
	int numSendProps = 0;
	int numFlatProps = 0;
	int numExcludeProps = 0;

	for ( int i=0; i < g_SendTables.Count(); i++ )
	{
		SendTable *st =  g_SendTables[i];
		
		numTables++;
		numSendProps += st->GetNumProps();
		numFlatProps += st->m_pPrecalc->GetNumProps();

		for ( int j=0; j < st->GetNumProps(); j++ )
		{
			SendProp* sp = st->GetProp( j );

			if ( sp->IsExcludeProp() )
			{
				numExcludeProps++;
				continue; // no real sendprops
			}

			if ( sp->IsInsideArray() )
				continue;

			switch( sp->GetType() )
			{
				case DPT_Int	: numInts++; break;
				case DPT_Float	: numFloats++; break;
				case DPT_Vector : numVecs++; break;
				case DPT_String : numStrings++; break;
				case DPT_Array	: numArrays++; break;
				case DPT_DataTable : numSubTables++; break;
			}
		}
	}

	Msg("Total Send Table stats\n");
	Msg("Send Tables : %i\n", numTables );
	Msg("Send Props  : %i\n", numSendProps );
	Msg("Flat Props  : %i\n", numFlatProps );
	Msg("Int Props   : %i\n", numInts );
	Msg("Float Props : %i\n", numFloats );
	Msg("Vector Props: %i\n", numVecs );
	Msg("String Props: %i\n", numStrings );
	Msg("Array Props : %i\n", numArrays );
	Msg("Table Props : %i\n", numSubTables );
	Msg("Exclu Props : %i\n", numExcludeProps );
}
Example #5
0
cell_t GetNumProps(IPluginContext *pContext, const cell_t *params) {
	Handle_t hndl = static_cast<Handle_t>(params[1]);
	HandleError err;
	HandleSecurity sec;
	sec.pOwner = NULL;
	sec.pIdentity = myself->GetIdentity();

	SendTable *pTable;

	if ((err=g_pHandleSys->ReadHandle(hndl, g_SendTableHandle, &sec, (void **)&pTable)) != HandleError_None)
	{
		return pContext->ThrowNativeError("Invalid SendTable handle %x (error %d)", hndl, err);
	}

	return pTable->GetNumProps();
}
	//---------------------------------------------------------------------------------
	// Purpose: used by the GetPropOffsetFromTable func to get a specific table
	//---------------------------------------------------------------------------------
	SendTable *GetDataTable( const char *pTableName, SendTable *pTable )
	{
		if (!pTable)
			return NULL;
		
		if ( FStrEq( pTableName, pTable->GetName() ) )
			return pTable;
		
		int num = pTable->GetNumProps();
		for (int i = 0; i < num; i++)
		{
			SendProp *pProp = pTable->GetProp(i);
			if (pProp)
			{
				SendTable *pSubTable = GetDataTable( pTableName, pProp->GetDataTable() );
				if (pSubTable == NULL)
					continue;
				if ( FStrEq(pSubTable->GetName(), pTableName) )
					return pSubTable;
			}
		}
		return NULL;
	}
// Spits out warnings for invalid properties and forces property values to
// be in valid ranges for the encoders and decoders.
static void SendTable_Validate( CSendTablePrecalc *pPrecalc )
{
	SendTable *pTable = pPrecalc->m_pSendTable;
	for( int i=0; i < pTable->m_nProps; i++ )
	{
		SendProp *pProp = &pTable->m_pProps[i];
		
		if ( pProp->GetArrayProp() )
		{
			if ( pProp->GetArrayProp()->GetType() == DPT_DataTable )
			{
				Error( "Invalid property: %s/%s (array of datatables) [on prop %d of %d (%s)].", pTable->m_pNetTableName, pProp->GetName(), i, pTable->m_nProps, pProp->GetArrayProp()->GetName() );
			}
		}
		else
		{
			ErrorIfNot( pProp->GetNumElements() == 1, ("Prop %s/%s has an invalid element count for a non-array.", pTable->m_pNetTableName, pProp->GetName()) );
		}
			
		// Check for 1-bit signed properties (their value doesn't get down to the client).
		if ( pProp->m_nBits == 1 && !(pProp->GetFlags() & SPROP_UNSIGNED) )
		{
			DataTable_Warning("SendTable prop %s::%s is a 1-bit signed property. Use SPROP_UNSIGNED or the client will never receive a value.\n", pTable->m_pNetTableName, pProp->GetName());
		}
	}

	for ( int i = 0; i < pPrecalc->GetNumProps(); ++i )
	{
		const SendProp *pProp = pPrecalc->GetProp( i );
		if ( pProp->GetFlags() & SPROP_ENCODED_AGAINST_TICKCOUNT )
		{
			pTable->SetHasPropsEncodedAgainstTickcount( true );
			break;
		}
	}
}
Example #8
0
bool MyPlugin::Load(CreateInterfaceFn interfaceFactory, CreateInterfaceFn gameServerFactory)
{
	serverGameDLL = (IServerGameDLL *)gameServerFactory(INTERFACEVERSION_SERVERGAMEDLL, NULL);
	if (serverGameDLL)
	{
		ServerClass *svrclass = serverGameDLL->GetAllServerClasses();
		while (svrclass)
		{
			const char *classname = svrclass->GetName();
			Msg("[%s]\n", classname);
			if (strcmp(classname, "CBasePlayer") == 0)
			{
				SendTable *st = svrclass->m_pTable;
				for (int i = 0; i < st->m_nProps; i++)
				{
					SendProp *sp = st->GetProp(i);
					const char *propname = sp->GetName();
					Msg("Prop name: %s | Prop Offset: %d | Type: %d | IsSigned: %d\n", propname, sp->GetOffset(), sp->GetType(), sp->IsSigned());
					
					if (strcmp(propname, "m_fFlags") == 0)
					{
						m_fFlags_off = sp->GetOffset();
						continue;
					}
					
					if (strcmp(propname, "m_iHealth") == 0)
					{
						m_iHealth_off = sp->GetOffset();
						continue;
					}
				}
			}
			
			if (strcmp(classname, "CBaseEntity") == 0)
			{
				SendTable *st = svrclass->m_pTable;
				for (int i = 0; i < st->m_nProps; i++)
				{
					SendProp *sp = st->GetProp(i);
					const char *propname = sp->GetName();
					Msg("Prop name: %s | Prop Offset: %d | Type: %d | IsSigned: %d\n", propname, sp->GetOffset(), sp->GetType(), sp->IsSigned());
					
					if (strcmp(propname, "m_iTeamNum") == 0)
					{
						m_iTeamNum_off = sp->GetOffset();
						continue;
					}
					
					if (strcmp(propname, "m_iPendingTeamNum") == 0)
					{
						m_iPendingTeamNum_off = sp->GetOffset();
						continue;
					}
					
					if (strcmp(propname, "m_fEffects") == 0)
					{
						m_fEffects_off = sp->GetOffset();
						continue;
					}
					
					if (strcmp(propname, "m_nRenderMode") == 0)
					{
						m_nRenderMode_off = sp->GetOffset();
						continue;
					}
				}
			}
			
			/*if (strcmp(classname, "CBaseCombatWeapon") == 0)
			{
				SendTable *st = svrclass->m_pTable;
				for (int i = 0; i < st->m_nProps; i++)
				{
					SendProp *sp = st->GetProp(i);
					const char *propname = sp->GetName();
					Msg("Prop name: %s | Prop Offset: %d | Type: %d | IsSigned: %d\n", propname, sp->GetOffset(), sp->GetType(), sp->IsSigned());
				}
			}*/
			svrclass = svrclass->m_pNext;
		}
	}
	else
	{
		Warning("Unable to load IServerGameDLL.\n");
		return false;
	}

	serverGameEnts = (IServerGameEnts *)gameServerFactory(INTERFACEVERSION_SERVERGAMEENTS, NULL);
	if (!serverGameEnts)
	{
		Warning("Unable to load IServerGameEnts.\n");
		return false;
	}

	playerInfoManager = (IPlayerInfoManager *)gameServerFactory(INTERFACEVERSION_PLAYERINFOMANAGER, NULL);
	if (playerInfoManager)
	{
		globalVars = playerInfoManager->GetGlobalVars();
	}
	else
	{
		Warning("Unable to load IPlayerInfoManager.\n");
		return false;
	}
	
	g_pCVar = (ICvar *)interfaceFactory(CVAR_INTERFACE_VERSION, NULL);
	if (g_pCVar)
	{
		ICvar::Iterator iter(g_pCVar);
		for (iter.SetFirst(); iter.IsValid(); iter.Next())
		{
			ConCommandBase *cmd = iter.Get();
			if (cmd->IsCommand())
				continue;
			const char *cmdname = cmd->GetName();
			ConVar *cvar = (ConVar *)cmd;
			if (strcmp(cmdname, "net_maxcleartime") == 0)
				cvar->SetValue(0.001f);

			/*if (strcmp(cmdname, "net_minroutable") == 0)
				cvar->SetValue(1000);*/
		}
	}
	else
	{
		Warning("Unable to load ICVar.\n");
		return false;
	}
	
	gameEventManager2 = (IGameEventManager2 *)interfaceFactory(INTERFACEVERSION_GAMEEVENTSMANAGER2, NULL);
	if (!gameEventManager2)
	{
		Warning("Unable to load IGameEventManager2.\n");
		return false;
	}

	vEngineServer = (IVEngineServer *)interfaceFactory(INTERFACEVERSION_VENGINESERVER, NULL);
	if (!vEngineServer)
	{
		Warning("Unable to load IVEngineServer.\n");
		return false;
	}

	serverTools = (IServerTools *)gameServerFactory(VSERVERTOOLS_INTERFACE_VERSION, NULL);
	if (!serverTools)
	{
		Warning("Unable to load IServerTools.\n");
		return false;
	}

	serverPluginHelpers = (IServerPluginHelpers *)interfaceFactory(INTERFACEVERSION_ISERVERPLUGINHELPERS, NULL);
	if (!serverPluginHelpers)
	{
		Warning("Unable to load IServerPluginHelpers.\n");
		return false;
	}

	//playerDeathEvent = new PlayerDeathEvent();
	//playerSayEvent = new PlayerSayEvent();
	//playerConnectEvent = new PlayerConnectEvent();
	//playerDisconnectEvent = new PlayerDisconnectEvent();
	roundStartEvent = new RoundStartEvent();
	//itemPickupEvent = new ItemPickupEvent();
	//playerSpawnEvent = new PlayerSpawnEvent();
	//playerSpawnedEvent = new PlayerSpawnedEvent();
	//announphaseendevent = new AnnouncePhaseEndEvent();

	return true;
}
Example #9
0
void RunDataTableTest()
{
	RecvTable *pRecvTable = &REFERENCE_RECV_TABLE(DT_DTTest);
	SendTable *pSendTable = &REFERENCE_SEND_TABLE(DT_DTTest);


	// Initialize the send and receive modules.
	SendTable_Init( &pSendTable, 1 );
	RecvTable_Init( &pRecvTable, 1 );

	pSendTable->SetWriteFlag( false );
	
	// Send DataTable info to the client.
	unsigned char commBuf[8192];
	bf_write bfWrite( "RunDataTableTest->commBuf", commBuf, sizeof(commBuf) );
	if( !WriteSendTable_R( pSendTable, bfWrite, true ) )
	{
		Assert( !"RunDataTableTest: SendTable_SendInfo failed." );
	}	
	bfWrite.WriteOneBit(0);


	// Receive the SendTable's info.
	bf_read bfRead( "RunDataTableTest->bfRead", commBuf, sizeof(commBuf));
	while( bfRead.ReadOneBit() )
	{
		bool bNeedsDecoder = bfRead.ReadOneBit()!=0;

		if( !RecvTable_RecvClassInfos( &bfRead, bNeedsDecoder ) )
		{
			Assert( !"RunDataTableTest: RecvTable_ReadInfos failed." );
			continue;
		}
	}

	// Register our receive table.
	if( !RecvTable_CreateDecoders( NULL ) )
	{
		Assert(false);
	}


	// Setup the data with all zeros.
	DTTestServer dtServer;
	DTTestClient dtClient;

	unsigned char prevEncoded[4096];
	unsigned char fullEncoded[4096];

	memset(&dtServer, 0, sizeof(dtServer));
	memset(&dtClient, 0, sizeof(dtClient));
	memset(prevEncoded, 0, sizeof(prevEncoded));

	SetGuardBytes( &dtClient );

	// Now loop around, changing the data a little bit each time and send/recv deltas.
	int nIterations = 25;
	for( int iIteration=0; iIteration < nIterations; iIteration++ )
	{
		// Change the server's data.
		g_bSendSub = true;
		if( (iIteration % 5) == 0 )
		{
			g_bSendSub = false; // every 8th time, don't send the subtable
		}
		
		if( (iIteration & 3) == 0 )
		{
			// Every once in a while, change ALL the properties.
			for( int iChange=0; iChange < NUMVARTESTINFOS; iChange++ )
				g_VarTestInfos[iChange].m_ChangeFn( &dtServer );
		}
		else
		{
			int nChanges = 3 + rand() % NUMVARTESTINFOS;
			for( int iChange=0; iChange < nChanges; iChange++ )
			{
				int iInfo = rand() % NUMVARTESTINFOS;
				g_VarTestInfos[iInfo].m_ChangeFn( &dtServer );
			}
		}

		// Fully encode it.
		bf_write bfFullEncoded( "RunDataTableTest->bfFullEncoded", fullEncoded, sizeof(fullEncoded) );
		if( !SendTable_Encode( pSendTable, &dtServer, &bfFullEncoded, -1, NULL ) )
		{
			Assert(false);
		}


		unsigned char deltaEncoded[4096];
		bf_write bfDeltaEncoded( "RunDataTableTest->bfDeltaEncoded", deltaEncoded, sizeof(deltaEncoded) );
		
		if ( iIteration == 0 )
		{
			// On the first iteration, just write the whole state.
			if( !SendTable_Encode( pSendTable, &dtServer, &bfDeltaEncoded, -1, NULL ) )
			{
				Assert( false );
			}
		}
		else
		{
			// Figure out the delta between the newly encoded one and the previously encoded one.
			int deltaProps[MAX_DATATABLE_PROPS];

			bf_read fullEncodedRead( "RunDataTableTest->fullEncodedRead", fullEncoded, sizeof( fullEncoded ), bfFullEncoded.GetNumBitsWritten() );
			bf_read prevEncodedRead( "RunDataTableTest->prevEncodedRead", prevEncoded, sizeof( prevEncoded ) );

			int nDeltaProps = SendTable_CalcDelta( 
				pSendTable, 
				prevEncoded, sizeof( prevEncoded ) * 8, 
				fullEncoded, bfFullEncoded.GetNumBitsWritten(),
				deltaProps,
				ARRAYSIZE( deltaProps ),
				-1 );
			
			Assert( nDeltaProps != -1 ); // BAD: buffer overflow

			
			// Reencode with just the delta. This is what is actually sent to the client.
			SendTable_WritePropList( 
				pSendTable,
				fullEncoded,
				bfFullEncoded.GetNumBitsWritten(),
				&bfDeltaEncoded,
				-1111, 
				deltaProps,
				nDeltaProps );
		}

		memcpy( prevEncoded, fullEncoded, sizeof( prevEncoded ) );


		// This step isn't necessary to have the client decode the data but it's here to test
		// RecvTable_CopyEncoding (and RecvTable_MergeDeltas). This call should just make an exact
		// copy of the encoded data.
		unsigned char copyEncoded[4096];
		bf_read bfReadDeltaEncoded( "RunDataTableTest->bfReadDeltaEncoded", deltaEncoded, sizeof( deltaEncoded ) );
		bf_write bfCopyEncoded( "RunDataTableTest->bfCopyEncoded", copyEncoded, sizeof(copyEncoded) );

		RecvTable_CopyEncoding( pRecvTable, &bfReadDeltaEncoded, &bfCopyEncoded, -1 );
		
		// Decode..
		bf_read bfDecode( "RunDataTableTest->copyEncoded", copyEncoded, sizeof( copyEncoded ) );
		if(!RecvTable_Decode(pRecvTable, &dtClient, &bfDecode, 1111))
		{
			Assert(false);
		}

		
		// Make sure it didn't go into memory it shouldn't have.
		CheckGuardBytes( &dtClient );


		// Verify that only the changed properties were sent and that they were received correctly.
		CompareDTTest( &dtClient, &dtServer );
	}

	SendTable_Term();
	RecvTable_Term();
}
Example #10
0
int EntityPropsManager::getPropOffset(const std::string &path)
{
	// Try to find if we have already this offset
	int iOffset = 0;
	int index = this->getIndexInList(path);
	if(index > -1)
	{
		iOffset = EntityPropsList.at(index).propOffset;
	}
	if(iOffset)
	{
		return iOffset;
	}
	// If not, we have to find it.

	iOffset = 0;
	int i = 0;
	std::string cpath;
	std::vector<std::string> props;

	strSplit(path, ".", &props);

	ServerClass *pAllClasses = gamedll->GetAllServerClasses();
	while(pAllClasses)
	{
		if(pAllClasses->GetName() == props.at(0)) // If we found the class
		{
			const int pSize = props.size(); // The use of const will accelerate the for instruction
			if(pSize > 2) // path containing class.datatable.(...).prop
			{
				SendTable *lastTable = pAllClasses->m_pTable;
				int iProps = 0;
				for(int iPath = 1; iPath < pSize-1; iPath++) // get the last datatable in path
				{
					cpath = props.at(iPath);
					iProps = lastTable->GetNumProps();
					for(i = 0; i < iProps; i++)
					{
						if(lastTable->GetProp(i)->GetName() == props.at(iPath))
						{
							lastTable = lastTable->GetProp(i)->GetDataTable();
							i = iProps;
						}
					}
				}
				iProps = lastTable->m_nProps;
				for(i = 0; i < iProps; i++) // get the prop offset
				{
					if(lastTable->GetProp(i)->GetName() == props.back())
					{
						iOffset = lastTable->GetProp(i)->GetOffset();
						if(iOffset < 0) // The offset must be not negative
						{
							iOffset *= -1;
						}
						return iOffset;
					}
				}
			}
			else // path containing only class.prop
			{
				const int iProps = pAllClasses->m_pTable->GetNumProps();
				for(i = 0; i < iProps; i++)
				{
					//Msg(pAllClasses->m_pTable->GetProp(i)->GetName());
					//Msg("\n");
					if(pAllClasses->m_pTable->GetProp(i)->GetName() == props.back())
					{
						iOffset = pAllClasses->m_pTable->GetProp(i)->GetOffset();
						if(iOffset < 0) // The offset must be not negative
						{
							iOffset *= -1;
						}
						return iOffset;
					}
				}
				break;
			}
		} // End if(pAllClasses->GetName() == props.at(0))
		pAllClasses = pAllClasses->m_pNext;
	} // End while(!pAllClasses)
	return 0;
}