From 46c54f829cb44745b4645a9f95c4381ea4fa6b9c Mon Sep 17 00:00:00 2001
From: Deathreus <csmoore96@yahoo.com>
Date: Mon, 15 Mar 2021 15:44:03 -0400
Subject: [PATCH] core: Call ConVarQueryFinished on client disconnect (#1384)

* Execute ConVarQueryFinished if client disconnects

So people passing handles to the extra data can close them, adds a new return value to check if this happened

* Update based on suggestion

Co-authored-by: Asher Baker <asherkin@limetech.io>

* Update based on notes

* Normalize

* Pass along cookie handle instead of invalid

Co-authored-by: Asher Baker <asherkin@limetech.io>
---
 core/ConVarManager.cpp      | 17 +++++++++++++++++
 plugins/include/convars.inc |  1 +
 2 files changed, 18 insertions(+)

diff --git a/core/ConVarManager.cpp b/core/ConVarManager.cpp
index 97639565..52700679 100644
--- a/core/ConVarManager.cpp
+++ b/core/ConVarManager.cpp
@@ -43,6 +43,10 @@ const ParamType CONVARCHANGE_PARAMS[] = {Param_Cell, Param_String, Param_String}
 typedef List<const ConVar *> ConVarList;
 NameHashSet<ConVarInfo *, ConVarInfo::ConVarPolicy> convar_cache;
 
+enum {
+	eQueryCvarValueStatus_Cancelled = -1,
+};
+
 class ConVarReentrancyGuard
 {
 	ConVar *cvar;
@@ -238,6 +242,19 @@ void ConVarManager::OnClientDisconnected(int client)
 		ConVarQuery &query = (*iter);
 		if (query.client == client)
 		{
+			IPluginFunction *pCallback = query.pCallback;
+			if (pCallback)
+			{
+				cell_t ret;
+
+				pCallback->PushCell(query.cookie);
+				pCallback->PushCell(client);
+				pCallback->PushCell(eQueryCvarValueStatus_Cancelled);
+				pCallback->PushString("");
+				pCallback->PushString("");
+				pCallback->PushCell(query.value);
+				pCallback->Execute(&ret);
+			}
 			iter = m_ConVarQueries.erase(iter);
 			continue;
 		}
diff --git a/plugins/include/convars.inc b/plugins/include/convars.inc
index 7bc9f770..7533a7f5 100644
--- a/plugins/include/convars.inc
+++ b/plugins/include/convars.inc
@@ -49,6 +49,7 @@ enum ConVarBounds
  */
 enum ConVarQueryResult
 {
+	ConVarQuery_Cancelled = -1,         //< Client disconnected during query */
 	ConVarQuery_Okay = 0,               //< Retrieval of client convar value was successful. */
 	ConVarQuery_NotFound,               //< Client convar was not found. */
 	ConVarQuery_NotValid,               //< A console command with the same name was found, but there is no convar. */