From 7465b20ed0b1b1c87c23c65beb1234fb2c2995a3 Mon Sep 17 00:00:00 2001 From: James Davis <6515965+The-Davis@users.noreply.github.com> Date: Fri, 1 Jan 2021 23:21:34 -0500 Subject: [PATCH] Adds ReportConsumableFulfillmentAsync function --- ...ReportConsumableFulfillmentAsyncWorker.cpp | 40 +++++++++++++++++++ src/ReportConsumableFulfillmentAsyncWorker.h | 24 +++++++++++ src/StoreContext.cpp | 23 ++++++++++- src/StoreContext.h | 1 + src/WindowsStoreImpl.cpp | 19 ++++++++- src/WindowsStoreImpl.h | 7 ++++ 6 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 src/ReportConsumableFulfillmentAsyncWorker.cpp create mode 100644 src/ReportConsumableFulfillmentAsyncWorker.h diff --git a/src/ReportConsumableFulfillmentAsyncWorker.cpp b/src/ReportConsumableFulfillmentAsyncWorker.cpp new file mode 100644 index 0000000..c0d63c7 --- /dev/null +++ b/src/ReportConsumableFulfillmentAsyncWorker.cpp @@ -0,0 +1,40 @@ +#include "ReportConsumableFulfillmentAsyncWorker.h" +#include +#include +#include +#include + +ReportConsumableFulfillmentAsyncWorker::ReportConsumableFulfillmentAsyncWorker( + const Napi::Function &callback, std::string addOnStoreId, int quantity, winrt::guid trackingId, WindowsStoreImpl *pImpl) + : Napi::AsyncWorker(callback), m_addonstoreid(addOnStoreId), m_quantity(quantity), m_trackingid(trackingId), m_pImpl(pImpl), + m_result(NULL, NULL) {} + +void ReportConsumableFulfillmentAsyncWorker::Execute() { + m_result = m_pImpl->ReportConsumableFulfillmentAsync(m_addonstoreid, m_quantity, m_trackingid); +} + +void ReportConsumableFulfillmentAsyncWorker::OnOK() { + Napi::Env env = Env(); + Napi::Object obj = Napi::Object::New(env); + if (m_result.extended_error != NULL) { + obj.Set("extendedError", m_result.extended_error); + } + if (m_result.status != NULL) { + obj.Set("status", m_result.status); + } + std::string returnTrackingId; + std::array convertGuid; + snprintf(convertGuid.data(), convertGuid.size(), "%08X-%04hX-%04hX-%02X%02X-%02X%02X%02X%02X%02X%02X", m_trackingid.Data1, m_trackingid.Data2, m_trackingid.Data3, m_trackingid.Data4[0], m_trackingid.Data4[1], m_trackingid.Data4[2], m_trackingid.Data4[3], m_trackingid.Data4[4], m_trackingid.Data4[5], m_trackingid.Data4[6], m_trackingid.Data4[7]); + returnTrackingId = convertGuid.data(); + obj.Set("TrackingId", returnTrackingId); + Callback().MakeCallback(Receiver().Value(), { + env.Null(), // error first callback + obj // this is apparently the value sent back to the callback + }); +} + +void ReportConsumableFulfillmentAsyncWorker::OnError(const Napi::Error &e) { + Napi::Env env = Env(); + + Callback().MakeCallback(Receiver().Value(), {e.Value(), env.Undefined()}); +} diff --git a/src/ReportConsumableFulfillmentAsyncWorker.h b/src/ReportConsumableFulfillmentAsyncWorker.h new file mode 100644 index 0000000..65792f6 --- /dev/null +++ b/src/ReportConsumableFulfillmentAsyncWorker.h @@ -0,0 +1,24 @@ +#pragma once + +#include "WindowsStoreImpl.h" +#include +#include + +class ReportConsumableFulfillmentAsyncWorker : public Napi::AsyncWorker { +public: + ReportConsumableFulfillmentAsyncWorker(const Napi::Function &callback, std::string addOnStoreId, + int quantity, winrt::guid trackingId, + WindowsStoreImpl *pImpl); + +protected: + virtual void Execute() override; + virtual void OnOK() override; + virtual void OnError(const Napi::Error &e) override; + +private: + WindowsStoreImpl *m_pImpl; + std::string m_addonstoreid; + int m_quantity; + winrt::guid m_trackingid; + WindowsStoreImpl::StoreConsumableStatus m_result; +}; diff --git a/src/StoreContext.cpp b/src/StoreContext.cpp index ba501f3..63fdfca 100644 --- a/src/StoreContext.cpp +++ b/src/StoreContext.cpp @@ -2,10 +2,13 @@ #include "GetCustomerPurchaseIdAsyncWorker.h" #include "GetStoreProductsAsyncWorker.h" #include "RequestPurchaseAsyncWorker.h" +#include "ReportConsumableFulfillmentAsyncWorker.h" #include "GetAppLicenseAsyncWorker.h" #include #include #include +#include +#include Napi::FunctionReference StoreContext::constructor; @@ -22,6 +25,7 @@ Napi::Object StoreContext::Init(Napi::Env env, Napi::Object exports) { InstanceMethod("getAssociatedStoreProductsAsync", &StoreContext::GetAssociatedStoreProductsAsync), InstanceMethod("getCustomerPurchaseIdAsync", &StoreContext::GetCustomerPurchaseIdAsync), InstanceMethod("requestPurchaseAsync", &StoreContext::RequestPurchaseAsync), + InstanceMethod("reportConsumableFulfillmentAsync", &StoreContext::ReportConsumableFulfillmentAsync), InstanceMethod("getAppLicenseAsync", &StoreContext::GetAppLicenseAsync), }); @@ -52,7 +56,7 @@ Napi::Value StoreContext::Initialize(const Napi::CallbackInfo &info) { Napi::HandleScope scope(env); Napi::Buffer bufferData = info[0].As>(); uint32_t handle = *reinterpret_cast(bufferData.Data()); - HWND hwnd = (HWND)handle; + HWND hwnd = (HWND)(UINT_PTR)handle; bool result = this->m_impl->Initialize(hwnd); return Napi::Boolean::New(info.Env(), result); } @@ -96,9 +100,24 @@ void StoreContext::RequestPurchaseAsync(const Napi::CallbackInfo &info) { (new RequestPurchaseAsyncWorker(cb, storeId, storePurchaseProperties, GetInternalInstance()))->Queue(); } +void StoreContext::ReportConsumableFulfillmentAsync(const Napi::CallbackInfo &info) { + Napi::Env env = info.Env(); + Napi::HandleScope scope(env); + if (info.Length() < 3) { + Napi::TypeError::New(env, "Too few arguments.").ThrowAsJavaScriptException(); + } + Napi::String addOnStoreId = info[0].As(); + int quantity = napi_get_value_int32(env, info[1], 0); + GUID trackingGuid; + CoCreateGuid(&trackingGuid); + winrt::guid trackingId = trackingGuid; + Napi::Function cb = info[2].As(); + (new ReportConsumableFulfillmentAsyncWorker(cb, addOnStoreId, quantity, trackingId, GetInternalInstance()))->Queue(); +} + void StoreContext::GetAppLicenseAsync(const Napi::CallbackInfo &info) { Napi::Env env = info.Env(); Napi::HandleScope scope(env); Napi::Function cb = info[0].As(); (new GetAppLicenseAsyncWorker(cb, GetInternalInstance()))->Queue(); -} \ No newline at end of file +} diff --git a/src/StoreContext.h b/src/StoreContext.h index bb95f3a..8842129 100644 --- a/src/StoreContext.h +++ b/src/StoreContext.h @@ -15,6 +15,7 @@ class StoreContext : public Napi::ObjectWrap { void GetAssociatedStoreProductsAsync(const Napi::CallbackInfo &info); void GetCustomerPurchaseIdAsync(const Napi::CallbackInfo &info); void RequestPurchaseAsync(const Napi::CallbackInfo &info); + void ReportConsumableFulfillmentAsync(const Napi::CallbackInfo &info); void GetAppLicenseAsync(const Napi::CallbackInfo &info); Napi::Value Initialize(const Napi::CallbackInfo &info); diff --git a/src/WindowsStoreImpl.cpp b/src/WindowsStoreImpl.cpp index 4c649e0..be68d70 100644 --- a/src/WindowsStoreImpl.cpp +++ b/src/WindowsStoreImpl.cpp @@ -197,4 +197,21 @@ WindowsStoreImpl::RequestPurchaseAsync(std::string storeId, StorePurchasePropert } else { return WindowsStoreImpl::StorePurchaseResult(result.ExtendedError(), NULL); } -} \ No newline at end of file +} + +WindowsStoreImpl::StoreConsumableStatus +WindowsStoreImpl::ReportConsumableFulfillmentAsync(std::string addOnStoreId, int quantity, winrt::guid trackingId) { + StoreContext context = StoreContext::GetDefault(); + auto initWindow = context.try_as(); + if (initWindow != nullptr) { + HRESULT hr = initWindow->Initialize(m_hwnd); + } + + auto result = context.ReportConsumableFulfillmentAsync(to_hstring(addOnStoreId), quantity, trackingId).get(); + + if (result.ExtendedError() == S_OK) { + return WindowsStoreImpl::StoreConsumableStatus(NULL, static_cast(result.Status())); + } else { + return WindowsStoreImpl::StoreConsumableStatus(result.ExtendedError(), NULL); + } +} diff --git a/src/WindowsStoreImpl.h b/src/WindowsStoreImpl.h index cd00b3d..bd4bd4f 100644 --- a/src/WindowsStoreImpl.h +++ b/src/WindowsStoreImpl.h @@ -21,6 +21,12 @@ class WindowsStoreImpl { StorePurchaseResult(int extendedError, int stat) : extended_error(extendedError), status(stat) {} }; + struct StoreConsumableStatus { + int extended_error; + int status; + StoreConsumableStatus(int extendedError, int stat) : extended_error(extendedError), status(stat) {} + }; + struct StoreProduct { std::string in_app_purchase_token; StoreProduct(std::string inAppPurchaseToken) : in_app_purchase_token(inAppPurchaseToken) {} @@ -45,6 +51,7 @@ class WindowsStoreImpl { StorePurchaseResult RequestPurchaseAsync(std::string storeId, winrt::Windows::Services::Store::StorePurchaseProperties &purchaseProperties); + StoreConsumableStatus ReportConsumableFulfillmentAsync(std::string addOnStoreId, int quantity, winrt::guid trackingId); private: bool GetIsMicrosoftAccrued(AttributionScope scope);