int Array_CompareDeltas( const SendProp *pProp, bf_read *p1, bf_read *p2 ) { SendProp *pArrayProp = pProp->GetArrayProp(); AssertMsg( pArrayProp, ("Array_CompareDeltas: missing m_pArrayProp for SendProp '%s'.", pProp->m_pVarName) ); int nLengthBits = pProp->GetNumArrayLengthBits(); int length1 = p1->ReadUBitLong( nLengthBits ); int length2 = p2->ReadUBitLong( nLengthBits ); int bDifferent = length1 != length2; // Compare deltas on the props that are the same. int nSame = min( length1, length2 ); for ( int iElement=0; iElement < nSame; iElement++ ) { bDifferent |= g_PropTypeFns[pArrayProp->GetType()].CompareDeltas( pArrayProp, p1, p2 ); } // Now just eat up the remaining properties in whichever buffer was larger. if ( length1 != length2 ) { bf_read *buffer = (length1 > length2) ? p1 : p2; int nExtra = max( length1, length2 ) - nSame; for ( int iEatUp=0; iEatUp < nExtra; iEatUp++ ) { SkipPropData( buffer, pArrayProp ); } } return bDifferent; }
void AddSendTable(SendTable* pTable, OffsetsMap& offsets, int offset=0, const char* baseName=NULL) { for (int i=0; i < pTable->GetNumProps(); ++i) { SendProp* pProp = pTable->GetProp(i); if (strcmp(pProp->GetName(), "baseclass") == 0) continue; int currentOffset = offset + pProp->GetOffset(); char* currentName = NULL; if (baseName == NULL) { currentName = (char*) pProp->GetName(); } else { char tempName[256]; sprintf(tempName, "%s.%s", baseName, pProp->GetName()); currentName = strdup(tempName); } if (pProp->GetType() == DPT_DataTable) { AddSendTable(pProp->GetDataTable(), offsets, currentOffset, currentName); } else { offsets.insert(std::make_pair(currentName, currentOffset)); } } }
void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level = 1) { SendProp *pProp; const char *type; for (int i = 0; i < pTable->GetNumProps(); i++) { pProp = pTable->GetProp(i); if (pProp->GetDataTable()) { fprintf(fp, "%*sTable: %s (offset %d) (type %s)\n", level, "", pProp->GetName(), pProp->GetOffset(), pProp->GetDataTable()->GetName()); UTIL_DrawSendTable(fp, pProp->GetDataTable(), level + 1); } else { type = GetDTTypeName(pProp->GetType()); if (type != NULL) { fprintf(fp, "%*sMember: %s (offset %d) (type %s) (bits %d) (%s)\n", level, "", pProp->GetName(), pProp->GetOffset(), type, pProp->m_nBits, UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType())); } else { fprintf(fp, "%*sMember: %s (offset %d) (type %d) (bits %d) (%s)\n", level, "", pProp->GetName(), pProp->GetOffset(), pProp->GetType(), pProp->m_nBits, UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType())); } } } }
void UTIL_DrawSendTable(FILE *fp, SendTable *pTable, int level) { char spaces[255]; for (int i=0; i<level; i++) spaces[i] = ' '; spaces[level] = '\0'; const char *name, *type; SendProp *pProp; fprintf(fp, "%sSub-Class Table (%d Deep): %s\n", spaces, level, pTable->GetName()); for (int i=0; i<pTable->GetNumProps(); i++) { pProp = pTable->GetProp(i); name = pProp->GetName(); if (pProp->GetDataTable()) { UTIL_DrawSendTable(fp, pProp->GetDataTable(), level + 1); } else { type = GetDTTypeName(pProp->GetType()); if (type != NULL) { fprintf(fp, "%s-Member: %s (offset %d) (type %s) (bits %d)\n", spaces, pProp->GetName(), pProp->GetOffset(), type, pProp->m_nBits); } else { fprintf(fp, "%s-Member: %s (offset %d) (type %d) (bits %d)\n", spaces, pProp->GetName(), pProp->GetOffset(), pProp->GetType(), pProp->m_nBits); } } } }
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 ); }
void UTIL_DrawSendTable_XML(FILE *fp, SendTable *pTable, int space_count) { char spaces[255]; for (int i = 0; i < space_count; i++) { spaces[i] = ' '; } spaces[space_count] = '\0'; const char *type_name; SendTable *pOtherTable; SendProp *pProp; fprintf(fp, " %s<sendtable name=\"%s\">\n", spaces, pTable->GetName()); for (int i = 0; i < pTable->GetNumProps(); i++) { pProp = pTable->GetProp(i); fprintf(fp, " %s<property name=\"%s\">\n", spaces, pProp->GetName()); if ((type_name = GetDTTypeName(pProp->GetType())) != NULL) { fprintf(fp, " %s<type>%s</type>\n", spaces, type_name); } else { fprintf(fp, " %s<type>%d</type>\n", spaces, pProp->GetType()); } fprintf(fp, " %s<offset>%d</offset>\n", spaces, pProp->GetOffset()); fprintf(fp, " %s<bits>%d</bits>\n", spaces, pProp->m_nBits); fprintf(fp, " %s<flags>%s</flags>\n", spaces, UTIL_SendFlagsToString(pProp->GetFlags(), pProp->GetType())); if ((pOtherTable = pTable->GetProp(i)->GetDataTable()) != NULL) { UTIL_DrawSendTable_XML(fp, pOtherTable, space_count + 3); } fprintf(fp, " %s</property>\n", spaces); } fprintf(fp, " %s</sendtable>\n", spaces); }
void Array_SkipProp( const SendProp *pProp, bf_read *pIn ) { SendProp *pArrayProp = pProp->GetArrayProp(); AssertMsg( pArrayProp, ("Array_SkipProp: missing m_pArrayProp for a property.") ); int nElements = pIn->ReadUBitLong( pProp->GetNumArrayLengthBits() ); for ( int i=0; i < nElements; i++ ) { // skip over data g_PropTypeFns[pArrayProp->GetType()].SkipProp( pArrayProp, pIn ); } }
bool Array_IsEncodedZero( const SendProp *pProp, bf_read *pIn ) { SendProp *pArrayProp = pProp->GetArrayProp(); AssertMsg( pArrayProp, ("Array_IsEncodedZero: missing m_pArrayProp for a property.") ); int nElements = pIn->ReadUBitLong( pProp->GetNumArrayLengthBits() ); for ( int i=0; i < nElements; i++ ) { // skip over data g_PropTypeFns[pArrayProp->GetType()].IsEncodedZero( pArrayProp, pIn ); } return nElements == 0;; }
cell_t GetType(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(); SendProp *pProp; if ((err=g_pHandleSys->ReadHandle(hndl, g_SendTableHandle, &sec, (void **)&pProp)) != HandleError_None) { return pContext->ThrowNativeError("Invalid SendProp handle %x (error %d)", hndl, err); } return pProp->GetType(); }
static void SendTable_CalcNextVectorElems( SendTable *pTable ) { for ( int i=0; i < pTable->GetNumProps(); i++ ) { SendProp *pProp = pTable->GetProp( i ); if ( pProp->GetType() == DPT_DataTable ) { SendTable_CalcNextVectorElems( pProp->GetDataTable() ); } else if ( pProp->GetOffset() < 0 ) { pProp->SetOffset( -pProp->GetOffset() ); pProp->SetFlags( pProp->GetFlags() | SPROP_IS_A_VECTOR_ELEM ); } } }
void Array_Encode( const unsigned char *pStruct, DVariant *pVar, const SendProp *pProp, bf_write *pOut, int objectID ) { SendProp *pArrayProp = pProp->GetArrayProp(); AssertMsg( pArrayProp, ("Array_Encode: missing m_pArrayProp for SendProp '%s'.", pProp->m_pVarName) ); int nElements = Array_GetLength( pStruct, pProp, objectID ); // Write the number of elements. pOut->WriteUBitLong( nElements, pProp->GetNumArrayLengthBits() ); unsigned char *pCurStructOffset = (unsigned char*)pStruct + pArrayProp->GetOffset(); for ( int iElement=0; iElement < nElements; iElement++ ) { DVariant var; // Call the proxy to get the value, then encode. pArrayProp->GetProxyFn()( pArrayProp, pStruct, pCurStructOffset, &var, iElement, objectID ); g_PropTypeFns[pArrayProp->GetType()].Encode( pStruct, &var, pArrayProp, pOut, objectID ); pCurStructOffset += pProp->GetElementStride(); } }
void EntityProp::getOffset(SendTable * table, istringstream & propPathLeft) { // Get the next step into the props table string pathNextStep; getline(propPathLeft, pathNextStep, '.'); //Msg("Scanning %s...\n", propPathLeft.c_str()); int nbrProps = table->GetNumProps(); int i=0; while(i<nbrProps) { SendProp * sProp = table->GetProp(i); if (pathNextStep == sProp->GetName()) { offset += sProp->GetOffset(); switch(sProp->GetType()) { case DPT_Int: case DPT_Float: case DPT_Vector: case DPT_String: case DPT_Array: // Found the prop itself, the offset is up to date i = nbrProps; // break break; case DPT_DataTable: // Step reached, go to the next step getOffset(sProp->GetDataTable(), propPathLeft); break; default: // Prop not found offset = 0; i = nbrProps; // break } } i++; } }
cell_t GetTypeString(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(); SendProp *pProp; if ((err=g_pHandleSys->ReadHandle(hndl, g_SendTableHandle, &sec, (void **)&pProp)) != HandleError_None) { return pContext->ThrowNativeError("Invalid SendProp handle %x (error %d)", hndl, err); } const char *sType = GetDTTypeName(pProp->GetType()); if(sType != NULL) { pContext->StringToLocal(params[2], params[3], sType); return strlen(sType); } return 0; }
void Array_Decode( DecodeInfo *pInfo ) { SendProp *pArrayProp = pInfo->m_pProp->GetArrayProp(); AssertMsg( pArrayProp, ("Array_Decode: missing m_pArrayProp for a property.") ); // Setup a DecodeInfo that is used to decode each of the child properties. DecodeInfo subDecodeInfo; subDecodeInfo.CopyVars( pInfo ); subDecodeInfo.m_pProp = pArrayProp; int elementStride = 0; ArrayLengthRecvProxyFn lengthProxy = 0; if ( pInfo->m_pRecvProp ) { RecvProp *pArrayRecvProp = pInfo->m_pRecvProp->GetArrayProp(); subDecodeInfo.m_pRecvProp = pArrayRecvProp; // Note we get the OFFSET from the array element property and the STRIDE from the array itself. subDecodeInfo.m_pData = (char*)pInfo->m_pData + pArrayRecvProp->GetOffset(); elementStride = pInfo->m_pRecvProp->GetElementStride(); Assert( elementStride != -1 ); // (Make sure it was set..) lengthProxy = pInfo->m_pRecvProp->GetArrayLengthProxy(); } int nElements = pInfo->m_pIn->ReadUBitLong( pInfo->m_pProp->GetNumArrayLengthBits() ); if ( lengthProxy ) lengthProxy( pInfo->m_pStruct, pInfo->m_ObjectID, nElements ); for ( subDecodeInfo.m_iElement=0; subDecodeInfo.m_iElement < nElements; subDecodeInfo.m_iElement++ ) { g_PropTypeFns[pArrayProp->GetType()].Decode( &subDecodeInfo ); subDecodeInfo.m_pData = (char*)subDecodeInfo.m_pData + elementStride; } }
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; }
bool DataTable_SetupReceiveTableFromSendTable( SendTable *sendTable, bool bNeedsDecoder ) { CClientSendTable *pClientSendTable = new CClientSendTable; SendTable *pTable = &pClientSendTable->m_SendTable; g_ClientSendTables.AddToTail( pClientSendTable ); // Read the name. pTable->m_pNetTableName = COM_StringCopy( sendTable->m_pNetTableName ); // Create a decoder for it if necessary. if ( bNeedsDecoder ) { // Make a decoder for it. CRecvDecoder *pDecoder = new CRecvDecoder; g_RecvDecoders.AddToTail( pDecoder ); RecvTable *pRecvTable = FindRecvTable( pTable->m_pNetTableName ); if ( !pRecvTable ) { DataTable_Warning( "No matching RecvTable for SendTable '%s'.\n", pTable->m_pNetTableName ); return false; } pRecvTable->m_pDecoder = pDecoder; pDecoder->m_pTable = pRecvTable; pDecoder->m_pClientSendTable = pClientSendTable; pDecoder->m_Precalc.m_pSendTable = pClientSendTable->GetSendTable(); pClientSendTable->GetSendTable()->m_pPrecalc = &pDecoder->m_Precalc; // Initialize array properties. SetupArrayProps_R<RecvTable, RecvTable::PropType>( pRecvTable ); } // Read the property list. pTable->m_nProps = sendTable->m_nProps; pTable->m_pProps = pTable->m_nProps ? new SendProp[ pTable->m_nProps ] : 0; pClientSendTable->m_Props.SetSize( pTable->m_nProps ); for ( int iProp=0; iProp < pTable->m_nProps; iProp++ ) { CClientSendProp *pClientProp = &pClientSendTable->m_Props[iProp]; SendProp *pProp = &pTable->m_pProps[iProp]; const SendProp *pSendTableProp = &sendTable->m_pProps[ iProp ]; pProp->m_Type = (SendPropType)pSendTableProp->m_Type; pProp->m_pVarName = COM_StringCopy( pSendTableProp->GetName() ); pProp->SetFlags( pSendTableProp->GetFlags() ); if ( pProp->m_Type == DPT_DataTable ) { char *pDTName = pSendTableProp->m_pExcludeDTName; // HACK if ( pSendTableProp->GetDataTable() ) pDTName = pSendTableProp->GetDataTable()->m_pNetTableName; Assert( pDTName && Q_strlen(pDTName) > 0 ); pClientProp->SetTableName( COM_StringCopy( pDTName ) ); // Normally we wouldn't care about this but we need to compare it against // proxies in the server DLL in SendTable_BuildHierarchy. pProp->SetDataTableProxyFn( pSendTableProp->GetDataTableProxyFn() ); pProp->SetOffset( pSendTableProp->GetOffset() ); } else { if ( pProp->IsExcludeProp() ) { pProp->m_pExcludeDTName = COM_StringCopy( pSendTableProp->GetExcludeDTName() ); } else if ( pProp->GetType() == DPT_Array ) { pProp->SetNumElements( pSendTableProp->GetNumElements() ); } else { pProp->m_fLowValue = pSendTableProp->m_fLowValue; pProp->m_fHighValue = pSendTableProp->m_fHighValue; pProp->m_nBits = pSendTableProp->m_nBits; } } } return true; }