From c3b25e54f821f77153bc540c61141dad2ed78924 Mon Sep 17 00:00:00 2001 From: FlaminSarge Date: Sat, 28 Oct 2017 04:11:32 -0700 Subject: [PATCH] Add convenience logic for "offset" to Address definitions in GameConf (#580) Allows for the last "read" offset for an Address to instead be "offset", which doesn't deref the addr pointer after applying the offset Shortens the necessary coding to get a particular Address inside a function (old: store offset in a separate GameConf Offsets entry, apply the offset to the Address in SP) --- core/logic/GameConfigs.cpp | 30 ++++++++++++++++++++++++------ core/logic/GameConfigs.h | 4 +++- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/core/logic/GameConfigs.cpp b/core/logic/GameConfigs.cpp index c5704be0..2c59400f 100644 --- a/core/logic/GameConfigs.cpp +++ b/core/logic/GameConfigs.cpp @@ -323,6 +323,7 @@ SMCResult CGameConfig::ReadSMC_NewSection(const SMCStates *states, const char *n m_Address[0] = '\0'; m_AddressSignature[0] = '\0'; m_AddressReadCount = 0; + m_AddressLastIsOffset = false; strncopy(m_Address, name, sizeof(m_Address)); m_ParseState = PSTATE_GAMEDEFS_ADDRESSES_ADDRESS; @@ -430,10 +431,18 @@ SMCResult CGameConfig::ReadSMC_KeyValue(const SMCStates *states, const char *key } } } else if (m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS || m_ParseState == PSTATE_GAMEDEFS_ADDRESSES_ADDRESS_READ) { - if (strcmp(key, "read") == 0) { + if (strcmp(key, "read") == 0 || strcmp(key, "offset") == 0) { int limit = sizeof(m_AddressRead)/sizeof(m_AddressRead[0]); - if (m_AddressReadCount < limit) + if (m_AddressLastIsOffset) { + logger->LogError("[SM] Error parsing Address \"%s\", 'offset' entry must be the last entry (gameconf \"%s\")", m_Address, m_CurFile); + } + else if (m_AddressReadCount < limit) + { + if (strcmp(key, "offset") == 0) + { + m_AddressLastIsOffset = true; + } m_AddressRead[m_AddressReadCount] = atoi(value); m_AddressReadCount++; } @@ -637,7 +646,7 @@ SMCResult CGameConfig::ReadSMC_LeavingSection(const SMCStates *states) if (m_Address[0] != '\0' && m_AddressSignature[0] != '\0') { - AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead); + AddressConf addrConf(m_AddressSignature, sizeof(m_AddressSignature), m_AddressReadCount, m_AddressRead, m_AddressLastIsOffset); m_Addresses.replace(m_Address, addrConf); } @@ -997,12 +1006,17 @@ bool CGameConfig::GetAddress(const char *key, void **retaddr) int offset = addrConf.read[i]; //NULLs in the middle of an indirection chain are bad, end NULL is ok - if (addr == NULL || reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) + if (addr == NULL || reinterpret_cast(addr) < VALID_MINIMUM_MEMORY_ADDRESS) { *retaddr = NULL; return false; } - addr = *(reinterpret_cast(reinterpret_cast(addr) + offset)); + //If lastIsOffset is set and this is the last iteration of the loop, don't deref + if (addrConf.lastIsOffset && i == addrConf.readCount-1) { + addr = reinterpret_cast(reinterpret_cast(addr) + offset); + } else { + addr = *(reinterpret_cast(reinterpret_cast(addr) + offset)); + } } *retaddr = addr; @@ -1014,13 +1028,17 @@ static inline unsigned minOf(unsigned a, unsigned b) return a <= b ? a : b; } -CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read) +CGameConfig::AddressConf::AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read, bool lastIsOffset) { unsigned readLimit = minOf(readCount, sizeof(this->read) / sizeof(this->read[0])); strncopy(signatureName, sigName, sizeof(signatureName) / sizeof(signatureName[0])); this->readCount = readLimit; memcpy(&this->read[0], read, sizeof(this->read[0])*readLimit); + + //For safety: if the readLimit isn't the same as the readCount, then the + //last read value was definitely discarded, so lastIsOffset should be ignored + this->lastIsOffset = readLimit < readCount ? false : lastIsOffset; } SendProp *CGameConfig::GetSendProp(const char *key) diff --git a/core/logic/GameConfigs.h b/core/logic/GameConfigs.h index 2ed1de50..802b9ebb 100644 --- a/core/logic/GameConfigs.h +++ b/core/logic/GameConfigs.h @@ -103,8 +103,9 @@ private: char signatureName[64]; int readCount; int read[8]; + bool lastIsOffset; - AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read); + AddressConf(char *sigName, unsigned sigLength, unsigned readCount, int *read, bool lastIsOffset); AddressConf() {} }; @@ -113,6 +114,7 @@ private: char m_AddressSignature[64]; int m_AddressReadCount; int m_AddressRead[8]; + bool m_AddressLastIsOffset; StringHashMap m_Addresses; const char *m_pEngine; const char *m_pBaseEngine;