Skip to content

Commit

Permalink
Merge Allow the server to refresh sku's after initial load (pr-3056)
Browse files Browse the repository at this point in the history
c3cf69e - fix(commerce): allow the server to refresh sku's after initial load
  • Loading branch information
prikolium-cfx committed Jan 9, 2025
2 parents 7cc7add + c3cf69e commit c95b323
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 2 deletions.
12 changes: 11 additions & 1 deletion code/components/citizen-server-impl/src/ServerExtCommerce.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,8 @@ class ClientExtCommerceComponent : public fwRefCountable
fx::Client* m_client;

bool m_commerceDataLoaded;

std::chrono::milliseconds m_lastUpdate { 0 };

std::set<int> m_ownedSkus;

Expand All @@ -481,11 +483,18 @@ void ClientExtCommerceComponent::LoadCommerceData()
{
auto userId = GetUserId();

if (m_commerceDataLoaded || !userId)
// If we already have our commerce data, only allow the server to refresh it every 10 seconds so we're not spamming requests
if (!userId || (m_commerceDataLoaded && (msec() - m_lastUpdate) < 10s))
{
return;
}

// Reset our commerce data state so we can properly wait for it to load again (in case this is a refresh)
m_commerceDataLoaded = false;
// don't allow the client to re-fetch while we're doing the request, this will be set again further down
// once the request is finished
m_lastUpdate = msec();

fwRefContainer<ClientExtCommerceComponent> thisRef(this);

HttpRequestOptions opts;
Expand Down Expand Up @@ -564,6 +573,7 @@ std::optional<int> ClientExtCommerceComponent::GetUserId()

void ClientExtCommerceComponent::SetSkus(std::set<int>&& list)
{
m_lastUpdate = msec();
m_ownedSkus = std::move(list);
m_commerceDataLoaded = true;
}
Expand Down
30 changes: 29 additions & 1 deletion ext/native-decls/LoadPlayerCommerceDataExt.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,36 @@ apiset: server
void LOAD_PLAYER_COMMERCE_DATA_EXT(char* playerSrc);
```
Requests the commerce data from Tebex for the specified player, including the owned SKUs. Use `IS_PLAYER_COMMERCE_INFO_LOADED` to check if it has loaded.
Requests the commerce data from Tebex for the specified player, including the owned SKUs.
Use [`IS_PLAYER_COMMERCE_INFO_LOADED_EXT`](#_0x1D14F4FE) to check if it has loaded.
This will not automatically update whenever a client purchases a package, if you want to fetch new purchases you will need to call this native again.
This native will temporarily cache the players commerce data for 10 seconds, a call to this native after 10 seconds will re-fetch the players commerce data.
## Parameters
* **playerSrc**: The player handle
## Examples
```lua
RegisterNetEvent("doesOwnPackage", function(packageIdSku)
-- source isn't valid across waits, so we localize it
local source = source
-- input isn't right
if type(packageIdSku) ~= "number" then
return
end
-- The native will cache the results
LoadPlayerCommerceDataExt(source)
-- Wait for the players data to load
while not IsPlayerCommerceInfoLoadedExt(source) do
Wait(0)
end
-- Tell the client if they own the package or not
TriggerClientEvent("doesOwnPackage", source, DoesPlayerOwnSkuExt(source, packageIdSku))
end)
```

0 comments on commit c95b323

Please sign in to comment.