// vim: set ts=4 sw=4 tw=99 noet: // // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license #ifndef _INCLUDE_GAMECONFIG_H_ #define _INCLUDE_GAMECONFIG_H_ #include #include "CLibrarySys.h" #include #include #include #include #include #include class CGameConfig : public ITextListener_SMC, public IGameConfig, public ke::Refcounted { friend class CGameConfigManager; public: CGameConfig(const char *file); ~CGameConfig(); public: bool Reparse(char *error, size_t maxlength); bool EnterFile(const char *file, char *error, size_t maxlength); public: // ITextListener_SMC SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); SMCResult ReadSMC_LeavingSection(const SMCStates *states); public: // IGameConfig const char* GetKeyValue(const char *key); 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); public: // NameHashSet static inline bool matches(const char *key, const CGameConfig *value) { return strcmp(key, value->m_File) == 0; } private: struct OffsetClass { StringHashMap list; }; typedef StringHashMap> OffsetClassMap; typedef StringHashMap OffsetMap; char m_File[PLATFORM_MAX_PATH]; char m_CurrentPath[PLATFORM_MAX_PATH]; OffsetMap m_Offsets; OffsetClassMap m_OffsetsByClass; StringHashMap m_Keys; StringHashMap m_Sigs; int m_ParseState; unsigned int m_IgnoreLevel; char m_Class[64]; char m_Offset[64]; char m_Game[256]; bool m_FoundOffset; bool m_MatchedClasses; bool m_ShouldBeReadingDefault; bool m_HadGame; bool m_MatchedGame; bool m_HadEngine; bool m_MatchedEngine; bool m_MatchedPlatform; unsigned int m_CustomLevel; ITextListener_SMC* m_CustomHandler; struct AddressConf { char m_SignatureName[64]; size_t m_ReadCount; int m_ReadBytes[8]; AddressConf(const char *sigName, size_t sigLength, size_t readCount, int *read); AddressConf() {} }; char m_Address[64]; char m_AddressSignature[64]; int m_AddressReadCount; int m_AddressRead[8]; StringHashMap m_Addresses; char m_pEngine[64]; }; class CGameMasterReader : public ITextListener_SMC { public: void ReadSMC_ParseStart(); SMCResult ReadSMC_NewSection(const SMCStates *states, const char *name); SMCResult ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value); SMCResult ReadSMC_LeavingSection(const SMCStates *states); public: ke::Vector* m_FileList; unsigned int m_State; unsigned int m_IgnoreLevel; char m_CurrentPath[PLATFORM_MAX_PATH]; bool m_HadEngine; bool m_MatchedEngine; bool m_HadGame; bool m_MatchedGame; }; class CGameConfigManager : public IGameConfigManager { public: CGameConfigManager(); ~CGameConfigManager(); public: // IGameConfigManager bool LoadGameConfigFile(const char *file, IGameConfig **pConfig, char *error, size_t maxlength); void CloseGameConfigFile(IGameConfig *cfg); void AddUserConfigHook(const char *sectionname, ITextListener_SMC *listener); void RemoveUserConfigHook(const char *sectionname, ITextListener_SMC *listener); public: void OnAmxxStartup(); void RemoveCachedConfig(CGameConfig *config); private: NameHashSet m_Lookup; public: StringHashMap m_customHandlers; }; #define GET_OFFSET(classname, member) \ static int member = -1; \ if (member == -1) \ { \ TypeDescription type; \ if (!CommonConfig->GetOffsetByClass(classname, #member, &type) || type.fieldOffset < 0)\ { \ LogError(amx, AMX_ERR_NATIVE, "Invalid %s offset. Native %s is disabled", #member, __FUNCTION__);\ return 0; \ } \ member = type.fieldOffset; \ } extern CGameConfigManager ConfigManager; extern IGameConfig *CommonConfig; #endif // _INCLUDE_GAMECONFIG_H_