14#include <engine/igameeventsystem.h>
15#include <inetchannel.h>
16#include <netmessages.pb.h>
17#include <networksystem/inetworkmessages.h>
18#include <networksystem/netmessage.h>
33 _slotListener =
slots.Changed += [
this](
int slot) { _pending->Clear(
slot); };
49 return std::unexpected(_failure);
52Status ClientConVars::Install()
56 return std::unexpected(
Error::NotReady(
"engine interfaces unavailable"));
65 _interfaces.
NetworkMessages->FindNetworkMessagePartial(
"CSVCMsg_GetCvarValue");
68 return std::unexpected(
Error::Engine(
"the engine does not provide CSVCMsg_GetCvarValue"));
77 return std::unexpected(
hook.error());
80 _hook = std::move(*
hook);
103 if (_pending->Full(
slot))
108 const int cookie = _pending->NextCookie(
slot);
120 return _pending->Count(
slot);
125 _pending->ClearAll();
176 std::string_view value;
179 if (!
msg.has_value() ||
msg.value().find(
'\0') != std::string::npos)
bool Query(int slot, std::string_view cvarName, QueryCallback callback)
std::function< void(int slot, ClientConVarStatus status, std::string_view name, std::string_view value)> QueryCallback
ClientConVars(Interfaces &interfaces, const Bindings &bindings, SlotEvents &slots)
size_t PendingCount(int slot) const
constexpr int Value() const noexcept
Bookkeeping for ClientConVars: per-slot, cookie-keyed queries awaiting an answer.
"The occupant of this slot changed" - raised by PlayerManager, consumed below it.
static double MonotonicSeconds()
void Info(std::format_string< Args... > fmt, Args &&... args)
Result< Subscription > HookVirtual(std::string_view name, const VirtualFn< Ret(Object *, Args...)> &function, Before &&before, After &&after=nullptr)
Hook a gamedata-bound virtual function on objects sharing its class vtable.
int ClientSlot(const Bindings &bindings, const void *client)
static std::string ReadFile(const std::filesystem::path &path)
constexpr bool IsValidSlot(int slot)
ClientConVarStatus
How the client answered a convar query (CCLCMsg_RespondCvarValue::status_code).
@ NotFound
The client has no convar by that name.
@ Protected
The convar is marked protected; the client withholds its value.
@ Answered
The client reported the convar's current value.
@ NotAConVar
The name exists on the client but is a command, not a convar.
std::expected< void, Error > Status
@ Send
point the client at AddonDecision::Id and wait for its reconnect
VirtualFn< bool(EngineClient *, const CNetMessage *)> ProcessRespondCvarValue
static Error Engine(std::string detail)
static Error Unsupported(std::string detail)
static Error NotReady(std::string detail)
Centralized holder for all HL2SDK interface pointers.
IGameEventSystem * GameEventSystem
INetworkMessages * NetworkMessages
One outstanding client convar query, identified by the cookie sent to the client.