Added sm_dump_classes command

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401928
This commit is contained in:
Matt Woodrow 2008-03-12 00:43:35 +00:00
parent b1da7e1cf8
commit 352b131c35
4 changed files with 243 additions and 0 deletions

102
extensions/sdktools/util.h Normal file
View File

@ -0,0 +1,102 @@
/**
* vim: set ts=4 :
* =============================================================================
* SourceMod SDKTools Extension
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* =============================================================================
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 3.0, as published by the
* Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
* As a special exception, AlliedModders LLC gives you permission to link the
* code of this program (as well as its derivative works) to "Half-Life 2," the
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
* by the Valve Corporation. You must obey the GNU General Public License in
* all respects for all other code used. Additionally, AlliedModders LLC grants
* this exception to all derivative works. AlliedModders LLC defines further
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
* or <http://www.sourcemod.net/license.php>.
*
* Version: $Id: vcallbuilder.h 1566 2007-10-14 22:12:46Z faluco $
*/
#ifndef _INCLUDE_SOURCEMOD_UTIL_H_
#define _INCLUDE_SOURCEMOD_UTIL_H_
#include "utldict.h"
abstract_class IEntityFactory
{
public:
virtual IServerNetworkable *Create( const char *pClassName ) = 0;
virtual void Destroy( IServerNetworkable *pNetworkable ) = 0;
virtual size_t GetEntitySize() = 0;
};
template <class T>
class CEntityFactory : public IEntityFactory
{
public:
CEntityFactory( const char *pClassName )
{
EntityFactoryDictionary()->InstallFactory( this, pClassName );
}
IServerNetworkable *Create( const char *pClassName )
{
T* pEnt = _CreateEntityTemplate((T*)NULL, pClassName);
return pEnt->NetworkProp();
}
void Destroy( IServerNetworkable *pNetworkable )
{
if ( pNetworkable )
{
pNetworkable->Release();
}
}
virtual size_t GetEntitySize()
{
return sizeof(T);
}
};
abstract_class IEntityFactoryDictionary
{
public:
virtual void InstallFactory( IEntityFactory *pFactory, const char *pClassName ) = 0;
virtual IServerNetworkable *Create( const char *pClassName ) = 0;
virtual void Destroy( const char *pClassName, IServerNetworkable *pNetworkable ) = 0;
virtual IEntityFactory *FindFactory( const char *pClassName ) = 0;
virtual const char *GetCannonicalName( const char *pClassName ) = 0;
};
class CEntityFactoryDictionary : public IEntityFactoryDictionary
{
public:
CEntityFactoryDictionary();
virtual void InstallFactory( IEntityFactory *pFactory, const char *pClassName );
virtual IServerNetworkable *Create( const char *pClassName );
virtual void Destroy( const char *pClassName, IServerNetworkable *pNetworkable );
virtual const char *GetCannonicalName( const char *pClassName );
void ReportEntitySizes();
private:
IEntityFactory *FindFactory( const char *pClassName );
public:
CUtlDict< IEntityFactory *, unsigned short > m_Factories;
};
#endif //_INCLUDE_SOURCEMOD_UTIL_H_

View File

@ -30,6 +30,7 @@
*/ */
#include "extension.h" #include "extension.h"
#include "util.h"
#include "vhelpers.h" #include "vhelpers.h"
CallHelper s_Teleport; CallHelper s_Teleport;
@ -501,3 +502,116 @@ CON_COMMAND(sm_dump_netprops, "Dumps the networkable property table as a text fi
fclose(fp); fclose(fp);
} }
#if defined SUBPLATFORM_SECURECRT
void _ignore_invalid_parameter(
const wchar_t * expression,
const wchar_t * function,
const wchar_t * file,
unsigned int line,
uintptr_t pReserved
)
{
/* Wow we don't care, thanks Microsoft. */
}
#endif
CON_COMMAND(sm_dump_classes, "Dumps the class list as a text file")
{
#if !defined ORANGEBOX_BUILD
CCommand args;
#endif
if (args.ArgC() < 2)
{
META_CONPRINT("Usage: sm_dump_classes <file>\n");
return;
}
const char *file = args.Arg(1);
if (!file || file[0] == '\0')
{
META_CONPRINT("Usage: sm_dump_classes <file>\n");
return;
}
ICallWrapper *pWrapper = NULL;
if (!pWrapper)
{
PassInfo retData;
retData.flags = PASSFLAG_BYVAL;
retData.size = sizeof(void *);
retData.type = PassType_Basic;
void *addr;
if (!g_pGameConf->GetMemSig("EntityFactory", &addr) || addr == NULL)
{
META_CONPRINT("Failed to locate function\n");
return;
}
pWrapper = g_pBinTools->CreateCall(addr, CallConv_Cdecl, &retData, NULL, 0);
}
void *returnData = NULL;
pWrapper->Execute(NULL, &returnData);
pWrapper->Destroy();
if (returnData == NULL)
{
return;
}
CEntityFactoryDictionary *dict = ( CEntityFactoryDictionary * )returnData;
if ( !dict )
{
return;
}
char path[PLATFORM_MAX_PATH];
g_pSM->BuildPath(Path_Game, path, sizeof(path), "%s", file);
FILE *fp = NULL;
if ((fp = fopen(path, "wt")) == NULL)
{
META_CONPRINTF("Could not open file \"%s\"\n", path);
return;
}
char buffer[80];
buffer[0] = 0;
#if defined SUBPLATFORM_SECURECRT
_invalid_parameter_handler handler = _set_invalid_parameter_handler(_ignore_invalid_parameter);
#endif
time_t t = g_pSM->GetAdjustedTime();
size_t written = strftime(buffer, sizeof(buffer), "%d/%m/%Y", localtime(&t));
#if defined SUBPLATFORM_SECURECRT
_set_invalid_parameter_handler(handler);
#endif
fprintf(fp, "// Dump of all classes for \"%s\" as at %s\n//\n\n", g_pSM->GetGameFolderName(), buffer);
for ( int i = dict->m_Factories.First(); i != dict->m_Factories.InvalidIndex(); i = dict->m_Factories.Next( i ) )
{
IServerNetworkable *entity = dict->Create(dict->m_Factories.GetElementName(i));
ServerClass *sclass = entity->GetServerClass();
fprintf(fp,"%s - %s\n",sclass->GetName(), dict->m_Factories.GetElementName(i));
typedescription_t *datamap = gamehelpers->FindInDataMap(gamehelpers->GetDataMap(entity->GetBaseEntity()), "m_iEFlags");
int *eflags = (int *)((char *)entity->GetBaseEntity() + datamap->fieldOffset[TD_OFFSET_NORMAL]);
*eflags |= (1<<0); // EFL_KILLME
}
fclose(fp);
}

View File

@ -278,4 +278,17 @@
} }
} }
} }
/* EntityFactoryDictionary function */
"#default"
{
"Signatures"
{
"EntityFactory"
{
"library" "server"
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
"linux" "@_Z23EntityFactoryDictionaryv"
}
}
}
} }

View File

@ -1679,5 +1679,19 @@
} }
} }
} }
/* EntityFactoryDictionary function */
"#default"
{
"Signatures"
{
"EntityFactory"
{
"library" "server"
"windows" "\xB8\x01\x00\x00\x00\x84\x2A\x2A\x2A\x2A\x2A\x75\x1D\x09\x2A\x2A\x2A\x2A\x2A\xB9\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A\xE8\x2A\x2A\x2A\x2A\x83\xC4\x04\xB8\x2A\x2A\x2A\x2A\xC3"
"linux" "@_Z23EntityFactoryDictionaryv"
}
}
}
} }