From 7423ac68245772c4e5843d08e30b71456325cfc0 Mon Sep 17 00:00:00 2001 From: Arkshine Date: Sun, 9 Aug 2015 14:53:15 +0200 Subject: [PATCH] Modify game config parser to support more offset datas (type, size, etc.) --- amxmodx/CGameConfigs.cpp | 130 ++++++++++++++++++++++++++++++++------- amxmodx/CGameConfigs.h | 10 +-- public/IGameConfigs.h | 51 +++++++++++++-- 3 files changed, 161 insertions(+), 30 deletions(-) diff --git a/amxmodx/CGameConfigs.cpp b/amxmodx/CGameConfigs.cpp index f6e21e9a..2b6e5361 100644 --- a/amxmodx/CGameConfigs.cpp +++ b/amxmodx/CGameConfigs.cpp @@ -50,6 +50,8 @@ struct TempSigInfo } TempSig; +TypeDescription TempType; + static char ParseEngine[32]; static bool DoesGameMatch(const char *value) @@ -62,13 +64,10 @@ static bool DoesEngineMatch(const char* value) return strcmp(ParseEngine, value) == 0; } -CGameConfig::CGameConfig(const char *path) +CGameConfig::CGameConfig(const char *path) : m_FoundOffset(false), m_CustomLevel(0), m_CustomHandler(nullptr) { strncopy(m_File, path, sizeof(m_File)); strncopy(ParseEngine, IS_DEDICATED_SERVER() ? "engine_ds" : "engine_ls", sizeof(ParseEngine)); - - m_CustomLevel = 0; - m_CustomHandler = nullptr; } CGameConfig::~CGameConfig() @@ -180,9 +179,11 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n case PSTATE_GAMEDEFS_OFFSETS: { strncopy(m_Offset, name, sizeof(m_Offset)); + TempType.reset(); m_ParseState = PSTATE_GAMEDEFS_OFFSETS_OFFSET; m_MatchedPlatform = false; + m_FoundOffset = false; break; } case PSTATE_GAMEDEFS_SIGNATURES: @@ -250,26 +251,89 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key { case PSTATE_GAMEDEFS_OFFSETS_OFFSET: { - if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform)) + if (!strcmp(key, "type")) { - if (m_Class[0]) - { - auto ic = m_OffsetsByClass.findForAdd(m_Class); + auto type = FieldType::FIELD_NONE; - if (ic.found()) - { - ic->value->list.replace(m_Offset, atoi(value)); - } - else if (m_OffsetsByClass.add(ic, m_Class)) - { - ic->value = new OffsetClass; - ic->value->list.insert(m_Offset, atoi(value)); - } - } - else + if (!strcmp(value, "stringint")) { - m_Offsets.replace(m_Offset, atoi(value)); + type = FieldType::FIELD_STRINGINT; } + else if (!strcmp(value, "stringptr")) + { + type = FieldType::FIELD_STRINGPTR; + } + else if (!strcmp(value, "string")) + { + type = FieldType::FIELD_STRING; + } + else if (!strcmp(value, "classptr")) + { + type = FieldType::FIELD_CLASSPTR; + } + else if (!strcmp(value, "class")) + { + type = FieldType::FIELD_CLASS; + } + else if (!strcmp(value, "ehandle")) + { + type = FieldType::FIELD_EHANDLE; + } + else if (!strcmp(value, "edict")) + { + type = FieldType::FIELD_EDICT; + } + else if (!strcmp(value, "entvars")) + { + type = FieldType::FIELD_ENTVARS; + } + else if (!strcmp(value, "vector")) + { + type = FieldType::FIELD_VECTOR; + } + else if (!strcmp(value, "pointer")) + { + type = FieldType::FIELD_POINTER; + } + else if (!strcmp(value, "integer")) + { + type = FieldType::FIELD_INTEGER; + } + else if (!strcmp(value, "function")) + { + type = FieldType::FIELD_FUNCTION; + } + else if (!strcmp(value, "boolean")) + { + type = FieldType::FIELD_BOOLEAN; + } + else if (!strcmp(value, "short")) + { + type = FieldType::FIELD_SHORT; + } + else if (!strcmp(value, "character")) + { + type = FieldType::FIELD_CHARACTER; + } + else if (!strcmp(value, "float")) + { + type = FieldType::FIELD_FLOAT; + } + + TempType.fieldType = type; + } + else if (!strcmp(key, "size")) + { + TempType.fieldSize = ke::Min(0, atoi(value)); + } + else if (!strcmp(key, "unsigned")) + { + TempType.fieldUnsigned = !!atoi(value); + } + else if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform)) + { + m_FoundOffset = true; + TempType.fieldOffset = atoi(value); } break; } @@ -413,6 +477,28 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) } case PSTATE_GAMEDEFS_OFFSETS_OFFSET: { + if (m_FoundOffset) + { + if (m_Class[0]) + { + auto ic = m_OffsetsByClass.findForAdd(m_Class); + + if (ic.found()) + { + ic->value->list.replace(m_Offset, TempType); + } + else if (m_OffsetsByClass.add(ic, m_Class)) + { + ic->value = new OffsetClass; + ic->value->list.insert(m_Offset, TempType); + } + } + else + { + m_Offsets.replace(m_Offset, TempType); + } + } + m_ParseState = PSTATE_GAMEDEFS_OFFSETS; break; } @@ -671,12 +757,12 @@ bool CGameConfig::EnterFile(const char *file, char *error, size_t maxlength) return true; } -bool CGameConfig::GetOffset(const char *key, int *value) +bool CGameConfig::GetOffset(const char *key, TypeDescription *value) { return m_Offsets.retrieve(key, value); } -bool CGameConfig::GetOffsetByClass(const char *classname, const char *key, int *value) +bool CGameConfig::GetOffsetByClass(const char *classname, const char *key, TypeDescription *value) { auto r = m_OffsetsByClass.find(classname); diff --git a/amxmodx/CGameConfigs.h b/amxmodx/CGameConfigs.h index e908bdb7..3bb66449 100644 --- a/amxmodx/CGameConfigs.h +++ b/amxmodx/CGameConfigs.h @@ -45,8 +45,8 @@ class CGameConfig public: // IGameConfig const char* GetKeyValue(const char *key); - bool GetOffset(const char *key, int *value); - bool GetOffsetByClass(const char *classname, const char *key, int *value); + bool GetOffset(const char *key, TypeDescription *value); + bool GetOffsetByClass(const char *classname, const char *key, TypeDescription *value); bool GetMemSig(const char *key, void **addr); bool GetAddress(const char *key, void **addr); @@ -61,15 +61,16 @@ class CGameConfig struct OffsetClass { - StringHashMap list; + StringHashMap list; }; typedef StringHashMap> OffsetClassMap; + typedef StringHashMap OffsetMap; char m_File[PLATFORM_MAX_PATH]; char m_CurrentPath[PLATFORM_MAX_PATH]; - StringHashMap m_Offsets; + OffsetMap m_Offsets; OffsetClassMap m_OffsetsByClass; StringHashMap m_Keys; StringHashMap m_Sigs; @@ -81,6 +82,7 @@ class CGameConfig char m_Offset[64]; char m_Game[256]; + bool m_FoundOffset; bool m_MatchedClasses; bool m_ShouldBeReadingDefault; bool m_HadGame; diff --git a/public/IGameConfigs.h b/public/IGameConfigs.h index 1360e371..93246124 100644 --- a/public/IGameConfigs.h +++ b/public/IGameConfigs.h @@ -34,6 +34,49 @@ #include +enum class FieldType +{ + FIELD_NONE, + FIELD_FLOAT, // Floating point value + FIELD_STRINGINT, // String ID (return from ALLOC_STRING) + FIELD_STRINGPTR, // String, pointer-to-char + FIELD_STRING, // String, fixed size + FIELD_CLASSPTR, // Classes pointer derived of CBaseEntity + FIELD_CLASS, // Arbitrary classes, direct + FIELD_STRUCTURE, // Arbitrary structures, direct + FIELD_EHANDLE, // Entity handle + FIELD_ENTVARS, // entvars_t* + FIELD_EDICT, // edict_t* + FIELD_VECTOR, // Vector + FIELD_POINTER, // Arbitrary data pointer + FIELD_INTEGER, // Integer or enum + FIELD_FUNCTION, // Class function pointer (Think, Use, etc) + FIELD_BOOLEAN, // Boolean + FIELD_SHORT, // 2 bytes integer + FIELD_CHARACTER, // 1 byte +}; + +struct TypeDescription +{ + TypeDescription() + { + reset(); + } + + void reset() + { + fieldType = FieldType::FIELD_NONE; + fieldOffset = 0; + fieldSize = 0; + fieldUnsigned = false; + } + + FieldType fieldType; + int fieldOffset; + int fieldSize; + bool fieldUnsigned; +}; + /** * @brief Describes a game private data config file */ @@ -44,20 +87,20 @@ public: * @brief Returns an offset value. * * @param key Key to retrieve from the offset section. - * @param value Pointer to store the offset value in. + * @param value Pointer to store the TypeDescription reference in. * @return True if found, false otherwise. */ - virtual bool GetOffset(const char *key, int *value) = 0; + virtual bool GetOffset(const char *key, TypeDescription *value) = 0; /** * @brief Returns an offset value from given class. * * @param classname class name to match from the offset section. * @param key Key to retrieve from the offset section. - * @param value Pointer to store the offset value in. + * @param value Pointer to store the TypeDescription reference in. * @return True if found, false otherwise. */ - virtual bool GetOffsetByClass(const char *classname, const char *key, int *value) = 0; + virtual bool GetOffsetByClass(const char *classname, const char *key, TypeDescription *value) = 0; /** * @brief Returns the value of a key from the "Keys" section.