Browse Source

Separate out registration and injection processes

nosoop 1 year ago
parent
commit
fd8eb16101
3 changed files with 69 additions and 3 deletions
  1. 19 0
      econmanager.cpp
  2. 46 1
      econmanager.h
  3. 4 2
      mmsplugin.cpp

+ 19 - 0
econmanager.cpp

@@ -116,3 +116,22 @@ bool CEconManager::InsertOrReplaceAttribute(KeyValues *pAttribKV) {
 	g_SchemaAttributes->InsertOrReplace(attrdef, def);
 	return true;
 }
+
+bool CEconManager::RegisterAttribute(KeyValues* pAttribKV) {
+	KeyValues *pKV = new KeyValues(pAttribKV->GetName());
+	pAttribKV->CopySubkeys(pKV);
+	
+	AutoKeyValues kv{pKV};
+	std::string attrName = kv->GetString("name");
+	this->m_RegisteredAttributes[attrName] = std::move(kv);
+	return true;
+}
+
+void CEconManager::InstallAttributes() {
+	META_CONPRINTF("Installing attributes...\n");
+	for (const auto& pair : m_RegisteredAttributes) {
+		META_CONPRINTF("Getting attribute (%p)\n", (void *) pair.second.m_pKeyValues);
+		META_CONPRINTF("Installing attribute '%s'\n", pair.second->GetString("name"));
+		InsertOrReplaceAttribute(pair.second);
+	}
+}

+ 46 - 1
econmanager.h

@@ -3,6 +3,9 @@
 
 #include "mmsplugin.h"
 
+#include <map>
+#include <memory>
+
 #include <utlmap.h>
 #include <utlstring.h>
 #include <KeyValues.h>
@@ -39,11 +42,53 @@ public:
 	/* 0x40 */ string_t m_iszAttributeClass;
 };
 
-// handles 
+/**
+ * Copied implementation of KeyValues::AutoDelete.
+ */
+class AutoKeyValues {
+	public:
+	AutoKeyValues() : m_pKeyValues{nullptr} {}
+	
+	AutoKeyValues(KeyValues *pKeyValues) : m_pKeyValues{pKeyValues->MakeCopy()} {
+		META_CONPRINTF("Creating akv from kv %s (%p -> %p)\n", m_pKeyValues->GetString("name"), (void*) pKeyValues, (void *) m_pKeyValues);
+	}
+	AutoKeyValues(const AutoKeyValues &other) : m_pKeyValues{other.m_pKeyValues->MakeCopy()} {
+		META_CONPRINTF("Creating akv from akv %s (%p)\n", m_pKeyValues->GetString("name"), (void *) m_pKeyValues);
+	}
+	
+	~AutoKeyValues() {
+		if (m_pKeyValues) {
+			m_pKeyValues->deleteThis();
+		}
+	}
+	
+	KeyValues *operator->() const {
+		META_CONPRINTF("deref akv (%p)\n", (void*) m_pKeyValues);
+		return m_pKeyValues;
+	}
+	operator KeyValues *() const {
+		META_CONPRINTF("deref akv (%p)\n", (void*) m_pKeyValues);
+		return m_pKeyValues;
+	}
+	
+	KeyValues *m_pKeyValues;
+	private:
+};
+
+/**
+ * Keeps a copy of existing schema items to inject.
+ */
 class CEconManager {
 	public:
+	CEconManager() : m_RegisteredAttributes{} {}
+	
 	bool Init(char *error, size_t maxlength);
 	bool InsertOrReplaceAttribute(KeyValues *pAttribKV);
+	bool RegisterAttribute(KeyValues *pAttribKV);
+	void InstallAttributes();
+	
+	private:
+	std::map<std::string, AutoKeyValues> m_RegisteredAttributes;
 };
 
 // binary refers to 0x58 when iterating over the attribute map, so we'll refer to that value

+ 4 - 2
mmsplugin.cpp

@@ -84,7 +84,7 @@ bool DynSchema::Hook_LevelInitPost(const char *pMapName, char const *pMapEntitie
 		KeyValues *pKVAttributes = pKVMainConfig->FindKey( "attributes" );
 		if (pKVAttributes) {
 			FOR_EACH_TRUE_SUBKEY(pKVAttributes, kv) {
-				g_EconManager.InsertOrReplaceAttribute(kv);
+				g_EconManager.RegisterAttribute(kv);
 			}
 			META_CONPRINTF("Successfully injected custom schema %s\n", buffer);
 		} else {
@@ -106,7 +106,7 @@ bool DynSchema::Hook_LevelInitPost(const char *pMapName, char const *pMapEntitie
 			nativeAttribConfig->LoadFromFile(filesystem, pathbuf);
 			
 			FOR_EACH_TRUE_SUBKEY(nativeAttribConfig, kv) {
-				g_EconManager.InsertOrReplaceAttribute(kv);
+				g_EconManager.RegisterAttribute(kv);
 			}
 			
 			META_CONPRINTF("Discovered custom schema %s\n", pathbuf);
@@ -118,6 +118,8 @@ bool DynSchema::Hook_LevelInitPost(const char *pMapName, char const *pMapEntitie
 	// perhaps add some other validations before we actually process our attributes?
 	// TODO ensure the name doesn't clash with existing / newly injected attributes
 	
+	g_EconManager.InstallAttributes();
+	
 	return true;
 }