SMCResult CGameMasterReader::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) { if (m_IgnoreLevel || m_State != MSTATE_FILE) { return SMCResult_Continue; } if (strcmp(key, "engine") == 0) { m_HadEngine = true; if (DoesEngineMatch(value)) { m_MatchedEngine = true; } } else if (strcmp(key, "game") == 0) { m_HadGame = true; if (DoesGameMatch(value)) { m_MatchedGame = true; } } return SMCResult_Continue; }
SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) { if (m_IgnoreLevel) { return SMCResult_Continue; } switch (m_ParseState) { case PSTATE_GAMEDEFS_OFFSETS_OFFSET: { if (!strcmp(key, "type")) { auto type = FieldType::FIELD_NONE; if (!strcmp(value, "stringint")) { 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::Max<int>(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; } case PSTATE_GAMEDEFS_KEYS: { ke::AString vstr(value); m_Keys.replace(key, ke::Move(vstr)); break; } case PSTATE_GAMEDEFS_SUPPORTED: { if (strcmp(key, "game") == 0) { m_HadGame = true; if (DoesGameMatch(value)) { m_MatchedGame = true; } if ((!m_HadEngine && m_MatchedGame) || (m_MatchedEngine && m_MatchedGame)) { m_ShouldBeReadingDefault = true; } } else if (strcmp(key, "engine") == 0) { m_HadEngine = true; if (DoesEngineMatch(value)) { m_MatchedEngine = true; } if ((!m_HadGame && m_MatchedEngine) || (m_MatchedGame && m_MatchedEngine)) { m_ShouldBeReadingDefault = true; } } break; } case PSTATE_GAMEDEFS_SIGNATURES_SIG: { if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform)) { strncopy(TempSig.signature, value, sizeof(TempSig.signature)); } else if (strcmp(key, "library") == 0) { strncopy(TempSig.library, value, sizeof(TempSig.library)); } break; } case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS: case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ: { if (strcmp(key, "read") == 0) { int limit = sizeof(m_AddressRead) / sizeof(m_AddressRead[0]); if (m_AddressReadCount < limit) { m_AddressRead[m_AddressReadCount] = atoi(value); m_AddressReadCount++; } else { AMXXLOG_Error("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurrentPath); } } else if (strcmp(key, "signature") == 0) { strncopy(m_AddressSignature, value, sizeof(m_AddressSignature)); } break; } case PSTATE_GAMEDEFS_CUSTOM: { return m_CustomHandler->ReadSMC_KeyValue(states, key, value); } } return SMCResult_Continue; }
SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *name) { if (m_IgnoreLevel) { m_IgnoreLevel++; return SMCResult_Continue; } switch (m_ParseState) { case PSTATE_NONE: { if (strcmp(name, "Games") == 0) { m_ParseState = PSTATE_GAMES; } else { m_IgnoreLevel++; } break; } case PSTATE_GAMES: { if (strcmp(name, "*") == 0 || strcmp(name, "#default") == 0 || DoesGameMatch(name)) { m_ShouldBeReadingDefault = true; strncopy(m_Game, name, sizeof(m_Game)); m_Class[0] = '\0'; m_MatchedClasses = false; m_ParseState = PSTATE_GAMEDEFS; } else { m_IgnoreLevel++; } break; } case PSTATE_GAMEDEFS: case PSTATE_GAMEDEFS_CLASSES_CLASS: { if (strcmp(name, "Classes") == 0) { if (!m_Class[0]) { m_ParseState = PSTATE_GAMEDEFS_CLASSES; m_MatchedClasses = true; } else { ++m_IgnoreLevel; } break; } else if (strcmp(name, "Offsets") == 0) { m_ParseState = PSTATE_GAMEDEFS_OFFSETS; } else if (strcmp(name, "Keys") == 0) { m_ParseState = PSTATE_GAMEDEFS_KEYS; } else if (strcmp(name, "#supported") == 0 && strcmp(m_Game, "#default") == 0) { m_ParseState = PSTATE_GAMEDEFS_SUPPORTED; m_ShouldBeReadingDefault = false; m_HadGame = false; m_MatchedGame = false; m_HadEngine = false; m_MatchedEngine = false; } else if (strcmp(name, "Signatures") == 0) { m_ParseState = PSTATE_GAMEDEFS_SIGNATURES; } else if (strcmp(name, "Addresses") == 0) { m_ParseState = PSTATE_GAMEDEFS_ADDRESSES; } else { if (ConfigManager.m_customHandlers.retrieve(name, &m_CustomHandler)) { m_CustomLevel = 0; m_ParseState = PSTATE_GAMEDEFS_CUSTOM; m_CustomHandler->ReadSMC_ParseStart(); break; } ++m_IgnoreLevel; } break; } case PSTATE_GAMEDEFS_CLASSES: { strncopy(m_Class, name, sizeof(m_Class)); m_ParseState = PSTATE_GAMEDEFS_CLASSES_CLASS; break; } 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: { strncopy(m_Offset, name, sizeof(m_Offset)); TempSig.Reset(); m_ParseState = PSTATE_GAMEDEFS_SIGNATURES_SIG; m_MatchedPlatform = false; break; } case PSTATE_GAMEDEFS_CUSTOM: { ++m_CustomLevel; return m_CustomHandler->ReadSMC_NewSection(states, name); break; } case PSTATE_GAMEDEFS_ADDRESSES: { m_Address[0] = '\0'; m_AddressSignature[0] = '\0'; m_AddressReadCount = 0; strncopy(m_Address, name, sizeof(m_Address)); m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS; break; } case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS: { if (g_LibSys.DoesPlatformMatch(name)) { m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ; } else { if (strcmp(name, PLATFORM_LINUX_NAME) != 0 && strcmp(name, PLATFORM_WINDOWNS_NAME) != 0 && strcmp(name, PLATFORM_MAC_NAME) != 0) { AMXXLOG_Error("Error while parsing Address section for \"%s\" (%s):", m_Address, m_CurrentPath); AMXXLOG_Error("Unrecognized platform \"%s\"", name); } m_IgnoreLevel = 1; } break; } default: { m_IgnoreLevel++; break; } } return SMCResult_Continue; }
SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key, const char *value) { if (m_IgnoreLevel) { return SMCResult_Continue; } switch (m_ParseState) { case PSTATE_GAMEDEFS_OFFSETS_OFFSET: { if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform)) { if (m_Class[0]) { auto ic = m_OffsetsByClass.findForAdd(m_Class); 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 { m_Offsets.replace(m_Offset, atoi(value)); } } break; } case PSTATE_GAMEDEFS_KEYS: { ke::AString vstr(value); m_Keys.replace(key, ke::Move(vstr)); break; } case PSTATE_GAMEDEFS_SUPPORTED: { if (strcmp(key, "game") == 0) { m_HadGame = true; if (DoesGameMatch(value)) { m_MatchedGame = true; } if ((!m_HadEngine && m_MatchedGame) || (m_MatchedEngine && m_MatchedGame)) { m_ShouldBeReadingDefault = true; } } else if (strcmp(key, "engine") == 0) { m_HadEngine = true; if (DoesEngineMatch(value)) { m_MatchedEngine = true; } if ((!m_HadGame && m_MatchedEngine) || (m_MatchedGame && m_MatchedEngine)) { m_ShouldBeReadingDefault = true; } } break; } case PSTATE_GAMEDEFS_SIGNATURES_SIG: { if (g_LibSys.IsPlatformCompatible(key, &m_MatchedPlatform)) { strncopy(TempSig.signature, value, sizeof(TempSig.signature)); } else if (strcmp(key, "library") == 0) { strncopy(TempSig.library, value, sizeof(TempSig.library)); } break; } case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS: case PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ: { if (strcmp(key, "read") == 0) { int limit = sizeof(m_AddressRead) / sizeof(m_AddressRead[0]); if (m_AddressReadCount < limit) { m_AddressRead[m_AddressReadCount] = atoi(value); m_AddressReadCount++; } else { AMXXLOG_Error("[SM] Error parsing Address \"%s\", does not support more than %d read offsets (gameconf \"%s\")", m_Address, limit, m_CurrentPath); } } else if (strcmp(key, "signature") == 0) { strncopy(m_AddressSignature, value, sizeof(m_AddressSignature)); } break; } case PSTATE_GAMEDEFS_CUSTOM: { return m_CustomHandler->ReadSMC_KeyValue(states, key, value); } } return SMCResult_Continue; }