<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=GetEventClient</id>
	<title>GetEventClient - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://g1r-mp.com/wiki/index.php?action=history&amp;feed=atom&amp;title=GetEventClient"/>
	<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=GetEventClient&amp;action=history"/>
	<updated>2026-09-30T00:03:39Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://g1r-mp.com/wiki/index.php?title=GetEventClient&amp;diff=968&amp;oldid=prev</id>
		<title>QCherry: Release 0.1.4 BUILD133 / Protocol 36 and document authenticated event origin</title>
		<link rel="alternate" type="text/html" href="https://g1r-mp.com/wiki/index.php?title=GetEventClient&amp;diff=968&amp;oldid=prev"/>
		<updated>2026-09-21T20:37:18Z</updated>

		<summary type="html">&lt;p&gt;Release 0.1.4 BUILD133 / Protocol 36 and document authenticated event origin&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= getEventClient =&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Server-side. Available since 0.1.4.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
Returns the authenticated player ID that initiated the current synchronous request, or nil when no client request context exists.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
local playerId = getEventClient()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The value comes from native server context, not the writable Lua &amp;lt;code&amp;gt;client&amp;lt;/code&amp;gt; global. It survives synchronous nested &amp;lt;code&amp;gt;triggerEvent&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;executeCommandHandler&amp;lt;/code&amp;gt; calls, including cross-resource calls. Context is restored after handlers, including errors; simultaneous players do not share one persistent sender value.&lt;br /&gt;
&lt;br /&gt;
== Remote event contract ==&lt;br /&gt;
For a direct &amp;lt;code&amp;gt;triggerServerEvent&amp;lt;/code&amp;gt; request:&lt;br /&gt;
* The first callback argument remains the authenticated sender ID inserted by the server; client arguments follow it.&lt;br /&gt;
* &amp;lt;code&amp;gt;source&amp;lt;/code&amp;gt; is the sender&amp;#039;s player element; &amp;lt;code&amp;gt;sourceResource&amp;lt;/code&amp;gt; is nil; &amp;lt;code&amp;gt;eventOrigin&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;&amp;quot;client&amp;quot;&amp;lt;/code&amp;gt;.&lt;br /&gt;
* A client-supplied resource name is not a trusted identity.&lt;br /&gt;
&lt;br /&gt;
For server Lua forwarding, &amp;lt;code&amp;gt;sourceResource&amp;lt;/code&amp;gt; identifies the actual server resource and &amp;lt;code&amp;gt;eventOrigin&amp;lt;/code&amp;gt; is &amp;lt;code&amp;gt;&amp;quot;resource&amp;quot;&amp;lt;/code&amp;gt;. For native server events, origin is &amp;lt;code&amp;gt;&amp;quot;server&amp;quot;&amp;lt;/code&amp;gt;. Forwarding does not erase the initiating client. In command handlers, use this function rather than relying on event-only globals.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;lua&amp;quot;&amp;gt;&lt;br /&gt;
addEvent(&amp;quot;shop:buy&amp;quot;, true)&lt;br /&gt;
addEventHandler(&amp;quot;shop:buy&amp;quot;, root, function(playerId, productId)&lt;br /&gt;
    if getEventClient() ~= playerId then return end&lt;br /&gt;
    -- Validate product ID, player session, permissions, distance, quantity,&lt;br /&gt;
    -- price, balance and request rate using SERVER state before granting anything.&lt;br /&gt;
end)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Security and migration ==&lt;br /&gt;
* Leave private events remote-disabled: &amp;lt;code&amp;gt;addEvent(name, false)&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Remote subscriptions remain global by event name. &amp;lt;code&amp;gt;resourceRoot&amp;lt;/code&amp;gt; is not an authorization boundary; use namespaced names and validate every subscriber.&lt;br /&gt;
* Timers and asynchronous database/password/HTTP callbacks run later; they normally have nil client context. Capture player ID and a session token before scheduling, then revalidate them and permissions on completion. &amp;#039;&amp;#039;&amp;#039;nil is not proof of administrator authority.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Existing handlers authorizing clients by &amp;lt;code&amp;gt;sourceResource.name&amp;lt;/code&amp;gt; must migrate to the authenticated sender and server-owned permission checks.&lt;br /&gt;
* This does not stop a modified client from requesting an allowed event. It prevents trusting a forged source identity; scripts must still validate the requested operation. Server-installed Lua resources remain trusted.&lt;br /&gt;
&lt;br /&gt;
See [[TriggerServerEvent]], [[Lua events]] and [[Update 0.1.4]].&lt;br /&gt;
&lt;br /&gt;
[[Category:Lua Functions]]&lt;br /&gt;
[[Category:Server Functions]]&lt;br /&gt;
[[Category:Event Functions]]&lt;/div&gt;</summary>
		<author><name>QCherry</name></author>
	</entry>
</feed>