source_sdk_2013 0.1.0-alpha.8

Higher-level bindings for the Source SDK.
Documentation
//! `IServerPluginHelpers`, the engine's services for server plugins.

use crate::edicts::Edict;
use sdk_raw::interfaces::plugin_helpers::INVALID_QUERY_CVAR_COOKIE;
use sdk_raw::vcall;
use std::ffi::{CStr, c_int};

interface! {
	/// The engine's services for server plugins (`IServerPluginHelpers`).
	#[doc(alias("IServerPluginHelpers"))]
	pub struct PluginHelpers(sys::IServerPluginHelpers) = Engine sdk_raw::interfaces::plugin_helpers::VERSION;
}

/// Identifies a pending client console variable query.
///
/// [`PluginHelpers::start_query_cvar_value`] returns it, and the engine passes
/// it back to the plugin's `OnQueryCvarValueFinished` callback with the answer.
#[doc(alias("QueryCvarCookie_t"))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct QueryCvarCookie(pub c_int);

impl<'s> PluginHelpers<'s> {
	/// Injects one command into the server's client-command processing path,
	/// including for fake clients. Hooks and game events may run synchronously.
	///
	/// These calls count toward `sv_quota_stringcmdspersecond`. Engine console
	/// commands such as `status` can require a real incoming packet's client
	/// context; use the server console for those instead.
	#[doc(alias("ClientCommand"))]
	pub fn client_command(self, client: Edict<'_>, command: &CStr) {
		// SAFETY: `Server::new` guarantees the interface is live, and the edict is live.
		unsafe {
			vcall!(self.as_ptr() => IServerPluginHelpers_ClientCommand(client.as_ptr(), command.as_ptr()))
		};
	}

	/// Asks a client for the value of one of its console variables.
	///
	/// The answer arrives through the plugin's `OnQueryCvarValueFinished`
	/// callback, carrying the returned cookie. Returns `None` if the engine
	/// refuses the query with `InvalidQueryCvarCookie`, as it does for an
	/// invalid entity.
	#[doc(alias("StartQueryCvarValue"))]
	pub fn start_query_cvar_value(self, client: Edict<'_>, name: &CStr) -> Option<QueryCvarCookie> {
		// SAFETY: As for `client_command`.
		let cookie = unsafe {
			vcall!(self.as_ptr() => IServerPluginHelpers_StartQueryCvarValue(client.as_ptr(), name.as_ptr()))
		};

		(cookie != INVALID_QUERY_CVAR_COOKIE).then_some(QueryCvarCookie(cookie))
	}
}