Przeglądaj źródła

Separate out registration and injection processes

nosoop 1 rok temu
rodzic
commit
d8d25594f4
3 zmienionych plików z 56 dodań i 4 usunięć
  1. 16 1
      econmanager.cpp
  2. 36 1
      econmanager.h
  3. 4 2
      mmsplugin.cpp

+ 16 - 1
econmanager.cpp

@@ -9,7 +9,7 @@ using AttributeMap = CUtlMap<int, CEconItemAttributeDefinition, int>;
 AttributeMap *g_SchemaAttributes;
 
 size_t g_nAutoAttributeBase = 4000;
-std::map<std::string, int> g_AutoNumberedAttributes;
+std::map<std::string, int> g_AutoNumberedAttributes{};
 
 typedef uintptr_t (*GetEconItemSchema_fn)(void);
 GetEconItemSchema_fn fnGetEconItemSchema = nullptr;
@@ -116,3 +116,18 @@ bool CEconManager::InsertOrReplaceAttribute(KeyValues *pAttribKV) {
 	g_SchemaAttributes->InsertOrReplace(attrdef, def);
 	return true;
 }
+
+bool CEconManager::RegisterAttribute(KeyValues* pAttribKV) {
+	// for some reason any KV pointers we store blows up
+	// don't have the energy to deal with this shit
+	AutoKeyValues kv{pAttribKV->MakeCopy()};
+	std::string attrName = kv->GetString("name");
+	this->m_RegisteredAttributes[attrName] = std::move(kv);
+	return true;
+}
+
+void CEconManager::InstallAttributes() {
+	for (const auto& pair : m_RegisteredAttributes) {
+		InsertOrReplaceAttribute(pair.second);
+	}
+}

+ 36 - 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,43 @@ 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()} {}
+	AutoKeyValues(const AutoKeyValues &other) : m_pKeyValues{other.m_pKeyValues->MakeCopy()} {}
+	
+	~AutoKeyValues() {
+		if (m_pKeyValues) {
+			m_pKeyValues->deleteThis();
+		}
+	}
+	
+	KeyValues *operator->() const { return m_pKeyValues; }
+	operator KeyValues *() const { return m_pKeyValues; }
+	
+	private:
+	KeyValues *m_pKeyValues;
+};
+
+/**
+ * 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;
 }