bool FGameplayDebuggerCompat::Exec(UWorld* InWorld, const TCHAR* Cmd, FOutputDevice& Ar)
{
#if !(UE_BUILD_SHIPPING || UE_BUILD_TEST)
	bool bHandled = false;

	if (FParse::Command(&Cmd, TEXT("RunEQS")) && InWorld)
	{
		APlayerController* MyPC = InWorld->GetGameInstance() ? InWorld->GetGameInstance()->GetFirstLocalPlayerController() : nullptr;
		UAISystem* AISys = UAISystem::GetCurrent(*InWorld);

		UEnvQueryManager* EQS = AISys ? AISys->GetEnvironmentQueryManager() : NULL;
		if (MyPC && EQS)
		{
			AGameplayDebuggingReplicator* DebuggingReplicator = NULL;
			for (TActorIterator<AGameplayDebuggingReplicator> It(InWorld); It; ++It)
			{
				AGameplayDebuggingReplicator* A = *It;
				if (!A->IsPendingKill())
				{
					DebuggingReplicator = A;
					if (!DebuggingReplicator->IsGlobalInWorld() && DebuggingReplicator->GetLocalPlayerOwner() == MyPC)
					{
						break;
					}
				}
			}

			UObject* Target = DebuggingReplicator != NULL ? DebuggingReplicator->GetSelectedActorToDebug() : NULL;
			FString QueryName = FParse::Token(Cmd, 0);
			if (Target)
			{
				AISys->RunEQS(QueryName, Target);
			}
			else
			{
				MyPC->ClientMessage(TEXT("No debugging target to run EQS"));
			}
		}

		bHandled = true;
	}
	else if (FParse::Command(&Cmd, TEXT("EnableGDT")))
	{
		FString UniquePlayerId = FParse::Token(Cmd, 0);
		APlayerController* LocalPC = NULL;
		UWorld* MyWorld = InWorld;

		if (MyWorld == nullptr)
		{
			if (UniquePlayerId.Len() > 0)
			{
				// let's find correct world based on Player Id
				const TIndirectArray<FWorldContext> WorldContexts = GEngine->GetWorldContexts();
				for (const FWorldContext& Context : WorldContexts)
				{
					if (Context.WorldType != EWorldType::Game && Context.WorldType != EWorldType::PIE)
					{
						continue;
					}

					UWorld *CurrentWorld = Context.World();
					for (FConstPlayerControllerIterator Iterator = CurrentWorld->GetPlayerControllerIterator(); Iterator; ++Iterator)
					{
						APlayerController* PC = *Iterator;
						if (PC && PC->PlayerState->UniqueId.ToString() == UniquePlayerId)
						{
							LocalPC = PC;
							MyWorld = PC->GetWorld();
							break;
						}
					}

					if (LocalPC && MyWorld)
					{
						break;
					}
				}
			}
		}

		if (LocalPC == nullptr && MyWorld != nullptr)
		{
			if (UniquePlayerId.Len() > 0)
			{
				for (FConstPlayerControllerIterator Iterator = MyWorld->GetPlayerControllerIterator(); Iterator; ++Iterator)
				{
					APlayerController* PlayerController = *Iterator;
					UE_LOG(LogGameplayDebugger, Log, TEXT("- Client: %s"), *PlayerController->PlayerState->UniqueId.ToString());
					if (PlayerController && PlayerController->PlayerState->UniqueId.ToString() == UniquePlayerId)
					{
						LocalPC = PlayerController;
						break;
					}
				}
			}

			if (!LocalPC && MyWorld->GetNetMode() != NM_DedicatedServer)
			{
				LocalPC = MyWorld->GetGameInstance() ? MyWorld->GetGameInstance()->GetFirstLocalPlayerController() : nullptr;
			}
		}

		if (LocalPC != nullptr && MyWorld != nullptr)
		{
			if (MyWorld->GetNetMode() == NM_Client)
			{
				AGameplayDebuggingReplicator* Replicator = NULL;
				for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It)
				{
					Replicator = *It;
					if (Replicator && !Replicator->IsPendingKill())
					{
						APlayerController* PCOwner = Replicator->GetLocalPlayerOwner();
						if (LocalPC == PCOwner)
						{
							break;
						}
					}
					Replicator = NULL;
				}

				if (!Replicator)
				{
					LocalPC->ClientMessage(TEXT("Enabling GameplayDebugger on server, please wait for replicated data..."));
					if (LocalPC->PlayerState)
					{
						const FString ServerCheatString = FString::Printf(TEXT("cheat EnableGDT %s"), *LocalPC->PlayerState->UniqueId.ToString());
						UE_LOG(LogGameplayDebugger, Warning, TEXT("Sending to Server: %s"), *ServerCheatString);
						LocalPC->ConsoleCommand(*ServerCheatString);
					}
				}
				else
				{
					if (Replicator->IsToolCreated() == false)
					{
						Replicator->CreateTool();
						Replicator->EnableTool();
					}
					else
					{
						Replicator->EnableDraw(!Replicator->IsDrawEnabled());
					}
				}
			}
			else
			{
				UE_LOG(LogGameplayDebugger, Warning, TEXT("Got from client: EnableGDT %s"), *UniquePlayerId);
				{
					AGameplayDebuggingReplicator* Replicator = NULL;
					for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It)
					{
						Replicator = *It;
						if (Replicator && !Replicator->IsPendingKill())
						{
							APlayerController* PCOwner = Replicator->GetLocalPlayerOwner();
							if (LocalPC == PCOwner)
							{
								break;
							}
						}
						Replicator = NULL;
					}

					if (!Replicator)
					{
						CreateGameplayDebuggerForPlayerController(LocalPC);
						for (TActorIterator<AGameplayDebuggingReplicator> It(MyWorld); It; ++It)
						{
							Replicator = *It;
							if (Replicator && !Replicator->IsPendingKill())
							{
								APlayerController* PCOwner = Replicator->GetLocalPlayerOwner();
								if (LocalPC == PCOwner)
								{
									break;
								}
							}
							Replicator = NULL;
						}
					}

					if (MyWorld->GetNetMode() != NM_DedicatedServer)
					{
						if (Replicator && !Replicator->IsToolCreated())
						{
							Replicator->CreateTool();
							Replicator->EnableTool();
						}
					}
					else
					{
						if (Replicator)
						{
							Replicator->ClientAutoActivate();
						}
					}
				}
			}
		}

		bHandled = true;
	}

	return bHandled;
#else
	return false;
#endif //!(UE_BUILD_SHIPPING || UE_BUILD_TEST)
}