From b691c43c44ff180d10e7d4a9afc83b98551ff586 Mon Sep 17 00:00:00 2001 From: daoge_cmd <3523206925@qq.com> Date: Sun, 1 Mar 2026 12:16:08 +0800 Subject: Initial commit --- .../Orbis/Network/SonyCommerce_Orbis.cpp | 1314 ++++++++++++++++++++ 1 file changed, 1314 insertions(+) create mode 100644 Minecraft.Client/Orbis/Network/SonyCommerce_Orbis.cpp (limited to 'Minecraft.Client/Orbis/Network/SonyCommerce_Orbis.cpp') diff --git a/Minecraft.Client/Orbis/Network/SonyCommerce_Orbis.cpp b/Minecraft.Client/Orbis/Network/SonyCommerce_Orbis.cpp new file mode 100644 index 00000000..34ab67e4 --- /dev/null +++ b/Minecraft.Client/Orbis/Network/SonyCommerce_Orbis.cpp @@ -0,0 +1,1314 @@ +#include "stdafx.h" + +#include "SonyCommerce_Orbis.h" +#include "PS3\PS3Extras\ShutdownManager.h" +#include + + +bool SonyCommerce_Orbis::m_bCommerceInitialised = false; +// SceNpCommerce2SessionInfo SonyCommerce_Orbis::m_sessionInfo; +SonyCommerce_Orbis::State SonyCommerce_Orbis::m_state = e_state_noSession; +int SonyCommerce_Orbis::m_errorCode = 0; +LPVOID SonyCommerce_Orbis::m_callbackParam = NULL; + +void* SonyCommerce_Orbis::m_receiveBuffer = NULL; +SonyCommerce_Orbis::Event SonyCommerce_Orbis::m_event; +std::queue SonyCommerce_Orbis::m_messageQueue; +std::vector* SonyCommerce_Orbis::m_pProductInfoList = NULL; +SonyCommerce_Orbis::ProductInfoDetailed* SonyCommerce_Orbis::m_pProductInfoDetailed = NULL; +SonyCommerce_Orbis::ProductInfo* SonyCommerce_Orbis::m_pProductInfo = NULL; + +SonyCommerce_Orbis::CategoryInfo* SonyCommerce_Orbis::m_pCategoryInfo = NULL; +const char* SonyCommerce_Orbis::m_pProductID = NULL; +char* SonyCommerce_Orbis::m_pCategoryID = NULL; +SonyCommerce_Orbis::CheckoutInputParams SonyCommerce_Orbis::m_checkoutInputParams; +SonyCommerce_Orbis::DownloadListInputParams SonyCommerce_Orbis::m_downloadInputParams; + +SonyCommerce_Orbis::CallbackFunc SonyCommerce_Orbis::m_callbackFunc = NULL; +// sys_memory_container_t SonyCommerce_Orbis::m_memContainer = SYS_MEMORY_CONTAINER_ID_INVALID; +bool SonyCommerce_Orbis::m_bUpgradingTrial = false; + +SonyCommerce_Orbis::CallbackFunc SonyCommerce_Orbis::m_trialUpgradeCallbackFunc; +LPVOID SonyCommerce_Orbis::m_trialUpgradeCallbackParam; + +CRITICAL_SECTION SonyCommerce_Orbis::m_queueLock; + +uint32_t SonyCommerce_Orbis::m_contextId=0; ///< The npcommerce2 context ID +bool SonyCommerce_Orbis::m_contextCreated=false; ///< npcommerce2 context ID created? +SonyCommerce_Orbis::Phase SonyCommerce_Orbis::m_currentPhase = e_phase_stopped; ///< Current commerce2 util +// char SonyCommerce_Orbis::m_commercebuffer[SCE_NP_COMMERCE2_RECV_BUF_SIZE]; + +C4JThread* SonyCommerce_Orbis::m_tickThread = NULL; +bool SonyCommerce_Orbis::m_bLicenseChecked=false; // Check the trial/full license for the game + + + + +sce::Toolkit::NP::Utilities::Future > g_productList; +sce::Toolkit::NP::Utilities::Future g_categoryInfo; +sce::Toolkit::NP::Utilities::Future g_detailedProductInfo; + + +SonyCommerce_Orbis::ProductInfoDetailed s_trialUpgradeProductInfoDetailed; +void SonyCommerce_Orbis::Delete() +{ + m_pProductInfoList=NULL; + m_pProductInfoDetailed=NULL; + m_pProductInfo=NULL; + m_pCategoryInfo = NULL; + m_pProductID = NULL; + m_pCategoryID = NULL; +} + +void SonyCommerce_Orbis::Init() +{ + assert(m_state == e_state_noSession); + if(!m_bCommerceInitialised) + { + m_bCommerceInitialised = true; + m_pCategoryID=(char *)malloc(sizeof(char) * 100); + InitializeCriticalSection(&m_queueLock); + } +} + + + +void SonyCommerce_Orbis::CheckForTrialUpgradeKey_Callback(LPVOID param, bool bFullVersion) +{ + ProfileManager.SetFullVersion(bFullVersion); + if(ProfileManager.IsFullVersion()) + { + StorageManager.SetSaveDisabled(false); + ConsoleUIController::handleUnlockFullVersionCallback(); + // licence has been checked, so we're ok to install the trophies now +// ProfileManager.InitialiseTrophies( SQRNetworkManager_Orbis::GetSceNpCommsId(), +// SQRNetworkManager_Orbis::GetSceNpCommsSig()); +// + } + m_bLicenseChecked=true; +} + +bool SonyCommerce_Orbis::LicenseChecked() +{ + return m_bLicenseChecked; +} + +void SonyCommerce_Orbis::CheckForTrialUpgradeKey() +{ + StorageManager.CheckForTrialUpgradeKey(CheckForTrialUpgradeKey_Callback, NULL); +} + +int SonyCommerce_Orbis::Shutdown() +{ + int ret=0; + m_bCommerceInitialised = false; + if (m_contextCreated) + { + m_contextId = 0; + m_contextCreated = false; + } + + delete m_pCategoryID; + DeleteCriticalSection(&m_queueLock); + + // clear any possible callback function + m_callbackFunc = NULL; + + return ret; +} + + + +int SonyCommerce_Orbis::TickLoop(void* lpParam) +{ + ShutdownManager::HasStarted(ShutdownManager::eCommerceThread); + while( (m_currentPhase != e_phase_stopped) && ShutdownManager::ShouldRun(ShutdownManager::eCommerceThread) ) + { + processEvent(); + processMessage(); + Sleep(16); // sleep for a frame +// ((SonyCommerce_Orbis*)app.GetCommerce())->Test(); + } + + Shutdown(); + ShutdownManager::HasFinished(ShutdownManager::eCommerceThread); + + return 0; +} + +void SonyCommerce_Orbis::copyProductList(std::vector* pProductList, std::vector* pNPProductList) +{ + ProductInfo tempInfo; + std::vector tempProductVec; + // Reserve some space + int numProducts = pNPProductList->size(); + tempProductVec.reserve(numProducts); + for(int i=0;iat(i); + + // reset tempInfo + memset(&tempInfo, 0x0, sizeof(tempInfo)); + strncpy(tempInfo.productId, npInfo.productId, SCE_NP_COMMERCE2_PRODUCT_ID_LEN); + strncpy(tempInfo.productName, npInfo.productName, SCE_NP_COMMERCE2_PRODUCT_NAME_LEN); + strncpy(tempInfo.shortDescription, npInfo.shortDescription, SCE_NP_COMMERCE2_PRODUCT_SHORT_DESCRIPTION_LEN); + strcpy(tempInfo.longDescription,"Missing long description"); + strncpy(tempInfo.spName, npInfo.spName, SCE_NP_COMMERCE2_SP_NAME_LEN); + strncpy(tempInfo.imageUrl, npInfo.imageUrl, SCE_NP_COMMERCE2_URL_LEN); + tempInfo.releaseDate = npInfo.releaseDate; + tempInfo.purchasabilityFlag = npInfo.purchasabilityFlag; + // Take out the price. Nicely formatted + // but also keep the price as a value in case it's 0 - we need to show "free" for that + tempInfo.ui32Price = -1;// not available here + strncpy(tempInfo.price, npInfo.price, SCE_TOOLKIT_NP_SKU_PRICE_LEN); + tempProductVec.push_back(tempInfo); + } + pNPProductList->clear(); // clear the vector now we're done, this doesn't happen automatically for the next query + + // Set our result + *pProductList = tempProductVec; +} + +int SonyCommerce_Orbis::getProductList(std::vector* productList, char *categoryId) +{ + int ret; + sce::Toolkit::NP::ProductListInputParams params; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + + params.userInfo.userId = userId; + strcpy(params.categoryId, categoryId); + params.serviceLabel = 0; + app.DebugPrintf("Getting Product List ...\n"); + + ret = sce::Toolkit::NP::Commerce::Interface::getProductList(&g_productList, params, true); + if (ret < 0) + { + app.DebugPrintf("CommerceInterface::getProductList() error. ret = 0x%x\n", ret); + return ret; + } + + if (g_productList.hasResult()) + { + // result has returned immediately (don't think this should happen, but was handled in the samples + copyProductList(productList, g_productList.get()); + m_event = e_event_commerceGotProductList; + } + + return ret; +} + + + +void SonyCommerce_Orbis::copyCategoryInfo(CategoryInfo *pInfo, sce::Toolkit::NP::CategoryInfo *pNPInfo) +{ + strcpy(pInfo->current.categoryId, pNPInfo->current.categoryId); + strcpy(pInfo->current.categoryName, pNPInfo->current.categoryName); + strcpy(pInfo->current.categoryDescription, pNPInfo->current.categoryDescription); + strcpy(pInfo->current.imageUrl, pNPInfo->current.imageUrl); + pInfo->countOfProducts = pNPInfo->countOfProducts; + pInfo->countOfSubCategories = pNPInfo->countOfSubCategories; + if(pInfo->countOfSubCategories > 0) + { + std::list::iterator iter = pNPInfo->subCategories.begin(); + std::list::iterator iterEnd = pNPInfo->subCategories.end(); + + while(iter != iterEnd) + { + // For each sub category, obtain information + CategoryInfoSub tempSubCatInfo; + strcpy(tempSubCatInfo.categoryId, iter->categoryId); + strcpy(tempSubCatInfo.categoryName, iter->categoryName); + strcpy(tempSubCatInfo.categoryDescription, iter->categoryDescription); + strcpy(tempSubCatInfo.imageUrl, iter->imageUrl); + // Add to the list + pInfo->subCategories.push_back(tempSubCatInfo); + iter++; + } + } +} + +int SonyCommerce_Orbis::getCategoryInfo(CategoryInfo *pInfo, char *categoryId) +{ + + + int ret; + sce::Toolkit::NP::CategoryInfoInputParams params; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + + params.userInfo.userId = userId; + strcpy(params.categoryId, "");//categoryId); + params.serviceLabel = 0; + + app.DebugPrintf("Getting Category Information...\n"); + + ret = sce::Toolkit::NP::Commerce::Interface::getCategoryInfo(&g_categoryInfo, params, true); + if (ret < 0) + { + // error + app.DebugPrintf("Commerce::Interface::getCategoryInfo error: 0x%x\n", ret); + return ret; + } + else if (g_categoryInfo.hasResult()) + { + // result has returned immediately (don't think this should happen, but was handled in the samples + copyCategoryInfo(pInfo, g_categoryInfo.get()); + m_event = e_event_commerceGotCategoryInfo; + } + + return ret; +} + +void SonyCommerce_Orbis::copyDetailedProductInfo(ProductInfoDetailed *pInfo, sce::Toolkit::NP::ProductInfoDetailed* pNPInfo) +{ + // populate our temp struct + // pInfo->ratingDescriptors = npInfo.ratingSystemId; + strncpy(pInfo->productId, pNPInfo->productId, SCE_NP_COMMERCE2_PRODUCT_ID_LEN); + strncpy(pInfo->productName, pNPInfo->productName, SCE_NP_COMMERCE2_PRODUCT_NAME_LEN); + strncpy(pInfo->shortDescription, pNPInfo->shortDescription, SCE_NP_COMMERCE2_PRODUCT_SHORT_DESCRIPTION_LEN); + strncpy(pInfo->longDescription, pNPInfo->longDescription, SCE_NP_COMMERCE2_PRODUCT_LONG_DESCRIPTION_LEN); + strncpy(pInfo->legalDescription, pNPInfo->legalDescription, SCE_NP_COMMERCE2_PRODUCT_LEGAL_DESCRIPTION_LEN); + strncpy(pInfo->spName, pNPInfo->spName, SCE_NP_COMMERCE2_SP_NAME_LEN); + strncpy(pInfo->imageUrl, pNPInfo->imageUrl, SCE_NP_COMMERCE2_URL_LEN); + pInfo->releaseDate = pNPInfo->releaseDate; + strncpy(pInfo->ratingSystemId, pNPInfo->ratingSystemId, SCE_NP_COMMERCE2_RATING_SYSTEM_ID_LEN); + strncpy(pInfo->ratingImageUrl, pNPInfo->imageUrl, SCE_NP_COMMERCE2_URL_LEN); + strncpy(pInfo->skuId, pNPInfo->skuId, SCE_NP_COMMERCE2_SKU_ID_LEN); + pInfo->purchasabilityFlag = pNPInfo->purchasabilityFlag; + pInfo->ui32Price= pNPInfo->intPrice; + strncpy(pInfo->price, pNPInfo->price, SCE_TOOLKIT_NP_SKU_PRICE_LEN); + +} +int SonyCommerce_Orbis::getDetailedProductInfo(ProductInfoDetailed *pInfo, const char *productId, char *categoryId) +{ + int ret; + sce::Toolkit::NP::DetailedProductInfoInputParams params; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + + params.userInfo.userId = userId; + strcpy(params.categoryId, categoryId); + strcpy(params.productId, productId); + + + app.DebugPrintf("Getting Detailed Product Information ... \n"); + ret = sce::Toolkit::NP::Commerce::Interface::getDetailedProductInfo(&g_detailedProductInfo, params, true); + if (ret < 0) + { + app.DebugPrintf("CommerceInterface::getDetailedProductInfo() error. ret = 0x%x\n", ret); + return ret; + } + + if (g_detailedProductInfo.hasResult()) + { + // result has returned immediately (don't think this should happen, but was handled in the samples + copyDetailedProductInfo(pInfo, g_detailedProductInfo.get()); + m_event = e_event_commerceGotDetailedProductInfo; + } + return ret; +} + +void SonyCommerce_Orbis::copyAddDetailedProductInfo(ProductInfo *pInfo, sce::Toolkit::NP::ProductInfoDetailed* pNPInfo) +{ + + // populate our temp struct + // pInfo->ratingDescriptors = npInfo.ratingSystemId; + // strncpy(pInfo->productId, npInfo.productId, SCE_NP_COMMERCE2_PRODUCT_ID_LEN); + // strncpy(pInfo->productName, npInfo.productName, SCE_NP_COMMERCE2_PRODUCT_NAME_LEN); + // strncpy(pInfo->shortDescription, npInfo.shortDescription, SCE_NP_COMMERCE2_PRODUCT_SHORT_DESCRIPTION_LEN); + strncpy(pInfo->longDescription, pNPInfo->longDescription, SCE_NP_COMMERCE2_PRODUCT_LONG_DESCRIPTION_LEN); + // strncpy(pInfo->legalDescription, npInfo.legalDescription, SCE_NP_COMMERCE2_PRODUCT_LEGAL_DESCRIPTION_LEN); + // strncpy(pInfo->spName, npInfo.spName, SCE_NP_COMMERCE2_SP_NAME_LEN); + // strncpy(pInfo->imageUrl, npInfo.imageUrl, SCE_NP_COMMERCE2_URL_LEN); + // pInfo->releaseDate = npInfo.releaseDate; + // strncpy(pInfo->ratingSystemId, npInfo.ratingSystemId, SCE_NP_COMMERCE2_RATING_SYSTEM_ID_LEN); + // strncpy(pInfo->ratingImageUrl, npInfo.imageUrl, SCE_NP_COMMERCE2_URL_LEN); + strncpy(pInfo->skuId, pNPInfo->skuId, SCE_NP_COMMERCE2_SKU_ID_LEN); + pInfo->purchasabilityFlag = pNPInfo->purchasabilityFlag; + pInfo->ui32Price= pNPInfo->intPrice; + strncpy(pInfo->price, pNPInfo->price, SCE_TOOLKIT_NP_SKU_PRICE_LEN); + +} + +int SonyCommerce_Orbis::addDetailedProductInfo(ProductInfo *pInfo, const char *productId, char *categoryId) +{ + int ret; + sce::Toolkit::NP::DetailedProductInfoInputParams params; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + + params.userInfo.userId = userId; + strcpy(params.categoryId, categoryId); + strcpy(params.productId, productId); + + + app.DebugPrintf("Getting Detailed Product Information ... \n"); + ret = sce::Toolkit::NP::Commerce::Interface::getDetailedProductInfo(&g_detailedProductInfo, params, true); + if (ret < 0) + { + app.DebugPrintf("CommerceInterface::addDetailedProductInfo() error. ret = 0x%x\n", ret); + } + + if (g_detailedProductInfo.hasResult()) + { + // result has returned immediately (don't think this should happen, but was handled in the samples + copyAddDetailedProductInfo(pInfo, g_detailedProductInfo.get()); + m_event = e_event_commerceAddedDetailedProductInfo; + } + return ret; +} + + +int SonyCommerce_Orbis::checkout(CheckoutInputParams ¶ms) +{ + + int ret; + sce::Toolkit::NP::CheckoutInputParams npParams; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + npParams.userInfo.userId = userId; + npParams.serviceLabel = 0; + + std::list::iterator iter = params.skuIds.begin(); + std::list::iterator iterEnd = params.skuIds.end(); + while(iter != iterEnd) + { + npParams.skuIds.push_back((char*)*iter); // have to remove the const here, not sure why the libs pointers aren't const + iter++; + } + + app.DebugPrintf("Starting Checkout...\n"); + + ret = sce::Toolkit::NP::Commerce::Interface::checkout(npParams, false); + if (ret < 0) + { + app.DebugPrintf("Sample menu checkout() error. ret = 0x%x\n", ret); + } + + + return ret; +} + + +int SonyCommerce_Orbis::downloadList(DownloadListInputParams ¶ms) +{ + + int ret; + sce::Toolkit::NP::DownloadListInputParams npParams; + //memset(&npParams,0,sizeof(sce::Toolkit::NP::DownloadListInputParams)); + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + npParams.userInfo.userId = userId; + npParams.serviceLabel = 0; + npParams.skuIds.clear(); + + std::list::iterator iter = params.skuIds.begin(); + std::list::iterator iterEnd = params.skuIds.end(); + while(iter != iterEnd) + { + npParams.skuIds.push_back((char*)*iter); // have to remove the const here, not sure why the libs pointers aren't const + iter++; + } + + app.DebugPrintf("Starting Store Download List...\n"); + ret = sce::Toolkit::NP::Commerce::Interface::displayDownloadList(npParams, true); + if (ret < 0) + { + app.DebugPrintf("Commerce::Interface::displayDownloadList error: 0x%x\n", ret); + } + + return ret; +} + +int SonyCommerce_Orbis::checkout_game(CheckoutInputParams ¶ms) +{ + + int ret; + sce::Toolkit::NP::CheckoutInputParams npParams; + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + npParams.userInfo.userId = userId; + npParams.serviceLabel = 0; + + std::list::iterator iter = params.skuIds.begin(); + std::list::iterator iterEnd = params.skuIds.end(); + while(iter != iterEnd) + { + npParams.skuIds.push_back((char*)*iter); // have to remove the const here, not sure why the libs pointers aren't const + iter++; + } + + app.DebugPrintf("Starting Checkout...\n"); + sce::Toolkit::NP::ProductBrowseParams Myparams; + + Myparams.serviceLabel = 0; + Myparams.userInfo.userId = userId; + strncpy(Myparams.productId, "MINECRAFTPS40000", strlen("MINECRAFTPS40000")); + + ret = sce::Toolkit::NP::Commerce::Interface::productBrowse(Myparams, false); + if (ret < 0) { + // Error handling + } + + + //ret = sce::Toolkit::NP::Commerce::Interface::checkout(npParams, false); + if (ret < 0) + { + app.DebugPrintf("Sample menu checkout() error. ret = 0x%x\n", ret); + } + + + return ret; +} + +int SonyCommerce_Orbis::downloadList_game(DownloadListInputParams ¶ms) +{ + + int ret; + sce::Toolkit::NP::DownloadListInputParams npParams; + //memset(&npParams,0,sizeof(sce::Toolkit::NP::DownloadListInputParams)); + SceUserServiceUserId userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad()); + npParams.userInfo.userId = userId; + npParams.serviceLabel = 0; + npParams.skuIds.clear(); + + std::list::iterator iter = params.skuIds.begin(); + std::list::iterator iterEnd = params.skuIds.end(); + while(iter != iterEnd) + { + npParams.skuIds.push_back((char*)*iter); // have to remove the const here, not sure why the libs pointers aren't const + iter++; + } + + app.DebugPrintf("Starting Store Download List...\n"); +// ret = sce::Toolkit::NP::Commerce::Interface::displayDownloadList(npParams, true); +// if (ret < 0) +// { +// app.DebugPrintf("Commerce::Interface::displayDownloadList error: 0x%x\n", ret); +// } + + sce::Toolkit::NP::ProductBrowseParams Myparams; + + Myparams.serviceLabel = 0; + Myparams.userInfo.userId = userId; + strncpy(Myparams.productId, "MINECRAFTPS40000", strlen("MINECRAFTPS40000")); + + ret = sce::Toolkit::NP::Commerce::Interface::productBrowse(Myparams, false); + if (ret < 0) { + // Error handling + app.DebugPrintf("Commerce::Interface::displayDownloadList error: 0x%x\n", ret); + } + + + + return ret; +} + +void SonyCommerce_Orbis::UpgradeTrialCallback2(LPVOID lpParam,int err) +{ + SonyCommerce* pCommerce = (SonyCommerce*)lpParam; + app.DebugPrintf(4,"SonyCommerce_UpgradeTrialCallback2 : err : 0x%08x\n", err); + pCommerce->CheckForTrialUpgradeKey(); + if(err != SCE_OK) + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + C4JStorage::EMessageResult result = ui.RequestMessageBox( IDS_PRO_UNLOCKGAME_TITLE, IDS_NO_DLCOFFERS, uiIDA,1,ProfileManager.GetPrimaryPad()); + } + m_trialUpgradeCallbackFunc(m_trialUpgradeCallbackParam, m_errorCode); +} + +void SonyCommerce_Orbis::UpgradeTrialCallback1(LPVOID lpParam,int err) +{ + SonyCommerce* pCommerce = (SonyCommerce*)lpParam; + app.DebugPrintf(4,"SonyCommerce_UpgradeTrialCallback1 : err : 0x%08x\n", err); + if(err == SCE_OK) + { + char* skuID = s_trialUpgradeProductInfoDetailed.skuId; + if(s_trialUpgradeProductInfoDetailed.purchasabilityFlag == SCE_TOOLKIT_NP_COMMERCE_NOT_PURCHASED) + { + app.DebugPrintf(4,"UpgradeTrialCallback1 - Checkout\n"); + pCommerce->Checkout_Game(UpgradeTrialCallback2, pCommerce, skuID); + + + + } + else + { + app.DebugPrintf(4,"UpgradeTrialCallback1 - DownloadAlreadyPurchased\n"); + pCommerce->DownloadAlreadyPurchased_Game(UpgradeTrialCallback2, pCommerce, skuID); + } + } + else + { + UINT uiIDA[1]; + uiIDA[0]=IDS_CONFIRM_OK; + C4JStorage::EMessageResult result = ui.RequestMessageBox( IDS_PRO_UNLOCKGAME_TITLE, IDS_NO_DLCOFFERS, uiIDA,1,ProfileManager.GetPrimaryPad()); + m_trialUpgradeCallbackFunc(m_trialUpgradeCallbackParam, m_errorCode); + } +} + + + +// global func, so we can call from the profile lib +void SonyCommerce_UpgradeTrial() +{ + // we're now calling the app function here, which manages pending requests + app.UpgradeTrial(); +} + +void SonyCommerce_Orbis::UpgradeTrial(CallbackFunc cb, LPVOID lpParam) +{ + m_trialUpgradeCallbackFunc = cb; + m_trialUpgradeCallbackParam = lpParam; + +// static char szTrialUpgradeSkuID[64]; +// sprintf(szTrialUpgradeSkuID, "%s-TRIALUPGRADE0001", app.GetCommerceCategory());//, szSKUSuffix); + GetDetailedProductInfo(UpgradeTrialCallback1, this, &s_trialUpgradeProductInfoDetailed, app.GetUpgradeKey(), app.GetCommerceCategory()); +} + + +int SonyCommerce_Orbis::createContext() +{ +// SceNpId npId; +// int ret = sceNpManagerGetNpId(&npId); +// if(ret < 0) +// { +// app.DebugPrintf(4,"createContext sceNpManagerGetNpId problem\n"); +// return ret; +// } +// +// if (m_contextCreated) { +// ret = sceNpCommerce2DestroyCtx(m_contextId); +// if (ret < 0) +// { +// app.DebugPrintf(4,"createContext sceNpCommerce2DestroyCtx problem\n"); +// return ret; +// } +// } +// +// // Create commerce2 context +// ret = sceNpCommerce2CreateCtx(SCE_NP_COMMERCE2_VERSION, &npId, commerce2Handler, NULL, &m_contextId); +// if (ret < 0) +// { +// app.DebugPrintf(4,"createContext sceNpCommerce2CreateCtx problem\n"); +// return ret; +// } + + m_contextCreated = true; + + return SCE_OK; +} + +int SonyCommerce_Orbis::createSession() +{ + // From the Sony docs + // + // sce::Toolkit::NP::Commerce::Interface::CreateSession + // + // This function is provided to maintain compatibility with the PlayStationŽVita and PlayStationŽ3 platforms. Because commerce on the PlayStationŽ4 is not session based, SCE_TOOLKIT_NP_SUCCESS is always returned. + + int ret = sce::Toolkit::NP::Commerce::Interface::createSession(); + + if (ret < 0) + { + return ret; + } + m_currentPhase = e_phase_creatingSessionPhase; + + return ret; +} + + +void SonyCommerce_Orbis::commerce2Handler( const sce::Toolkit::NP::Event& event) +{ +// Event reply; +// reply.service = Toolkit::NP::commerce; +// + if(m_bCommerceInitialised==false) + { + // 4J-PB - this happens when we've signed out of the PSn, and we were in the process of retrieving DLC product info + // Ignore this event + app.DebugPrintf("@@@@@@@@ IGNORING COMMERCE EVENT AFTER COMMERCE SHUTDOWN @@@@@@@@@\n"); + return; + } + EnterCriticalSection(&m_queueLock); + + switch (event.event) + { + case sce::Toolkit::NP::Event::UserEvent::commerceError: + { + m_messageQueue.push(e_message_commerceEnd); + m_errorCode = event.returnCode; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceSessionCreated: + { + m_messageQueue.push(e_message_commerceEnd); + m_event = e_event_commerceSessionCreated; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceSessionAborted: + { + m_messageQueue.push(e_message_commerceEnd); + m_event = e_event_commerceSessionAborted; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceCheckoutStarted: + { + m_currentPhase = e_phase_checkoutPhase; + m_event = e_event_commerceCheckoutStarted; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceGotCategoryInfo: + { + copyCategoryInfo(m_pCategoryInfo, g_categoryInfo.get()); + m_pCategoryInfo = NULL; + m_event = e_event_commerceGotCategoryInfo; + break; + } + + case sce::Toolkit::NP::Event::UserEvent::commerceGotProductList: + { + copyProductList(m_pProductInfoList, g_productList.get()); + m_pProductInfoDetailed = NULL; + m_event = e_event_commerceGotProductList; + break; + } + + case sce::Toolkit::NP::Event::UserEvent::commerceGotDetailedProductInfo: + { + if(m_pProductInfoDetailed) + { + copyDetailedProductInfo(m_pProductInfoDetailed, g_detailedProductInfo.get()); + m_pProductInfoDetailed = NULL; + } + else + { + copyAddDetailedProductInfo(m_pProductInfo, g_detailedProductInfo.get()); + m_pProductInfo = NULL; + } + m_event = e_event_commerceGotDetailedProductInfo; + break; + } + + + +// case SCE_NP_COMMERCE2_EVENT_DO_CHECKOUT_SUCCESS: +// { +// m_messageQueue.push(e_message_commerceEnd); +// m_event = e_event_commerceCheckoutSuccess; +// break; +// } +// case SCE_NP_COMMERCE2_EVENT_DO_CHECKOUT_BACK: +// { +// m_messageQueue.push(e_message_commerceEnd); +// m_event = e_event_commerceCheckoutAborted; +// break; +// } + case sce::Toolkit::NP::Event::UserEvent::commerceCheckoutFinished: + { + m_event = e_event_commerceCheckoutFinished; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceDownloadListStarted: + { + m_currentPhase = e_phase_downloadListPhase; + m_event = e_event_commerceDownloadListStarted; + break; + } +// case SCE_NP_COMMERCE2_EVENT_DO_DL_LIST_SUCCESS: +// { +// m_messageQueue.push(e_message_commerceEnd); +// m_event = e_event_commerceDownloadListSuccess; +// break; +// } + case sce::Toolkit::NP::Event::UserEvent::commerceDownloadListFinished: + { + m_event = e_event_commerceDownloadListFinished; + break; + } + + case sce::Toolkit::NP::Event::UserEvent::commerceProductBrowseStarted: + { + m_currentPhase = e_phase_productBrowsePhase; + m_event = e_event_commerceProductBrowseStarted; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceProductBrowseSuccess: + { + m_messageQueue.push(e_message_commerceEnd); + m_event = e_event_commerceProductBrowseSuccess; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceProductBrowseAborted: + { + m_messageQueue.push(e_message_commerceEnd); + m_event = e_event_commerceProductBrowseAborted; + break; + } + case sce::Toolkit::NP::Event::UserEvent::commerceProductBrowseFinished: + { + m_event = e_event_commerceProductBrowseFinished; + break; + } + +// case SCE_NP_COMMERCE2_EVENT_DO_PROD_BROWSE_OPENED: +// break; +// case SCE_NP_COMMERCE2_EVENT_DO_PRODUCT_CODE_STARTED: +// { +// m_currentPhase = e_phase_voucherRedeemPhase; +// m_event = e_event_commerceVoucherInputStarted; +// break; +// } +// case SCE_NP_COMMERCE2_EVENT_DO_PRODUCT_CODE_SUCCESS: +// { +// m_messageQueue.push(e_message_commerceEnd); +// m_event = e_event_commerceVoucherInputSuccess; +// break; +// } +// case SCE_NP_COMMERCE2_EVENT_DO_PRODUCT_CODE_BACK: +// { +// m_messageQueue.push(e_message_commerceEnd); +// m_event = e_event_commerceVoucherInputAborted; +// break; +// } +// case SCE_NP_COMMERCE2_EVENT_DO_PRODUCT_CODE_FINISHED: +// { +// m_event = e_event_commerceVoucherInputFinished; +// break; +// } + default: + break; + }; + + LeaveCriticalSection(&m_queueLock); +} + + + +void SonyCommerce_Orbis::processMessage() +{ + EnterCriticalSection(&m_queueLock); + int ret; + if(m_messageQueue.empty()) + { + LeaveCriticalSection(&m_queueLock); + return; + } + Message msg = m_messageQueue.front(); + m_messageQueue.pop(); + + switch (msg) + { + + case e_message_commerceCreateSession: + ret = createSession(); + if (ret < 0) + { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + + case e_message_commerceGetCategoryInfo: + { + ret = getCategoryInfo(m_pCategoryInfo, m_pCategoryID); + if (ret < 0) + { + m_event = e_event_commerceError; + app.DebugPrintf(4,"ERROR - e_event_commerceGotCategoryInfo - %s\n",m_pCategoryID); + m_errorCode = ret; + } + break; + } + + case e_message_commerceGetProductList: + { + ret = getProductList(m_pProductInfoList, m_pCategoryID); + if (ret < 0) + { + m_event = e_event_commerceError; + } + break; + } + + case e_message_commerceGetDetailedProductInfo: + { + ret = getDetailedProductInfo(m_pProductInfoDetailed, m_pProductID, m_pCategoryID); + if (ret < 0) + { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + case e_message_commerceAddDetailedProductInfo: + { + ret = addDetailedProductInfo(m_pProductInfo, m_pProductID, m_pCategoryID); + if (ret < 0) + { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + +// +// case e_message_commerceStoreProductBrowse: +// { +// ret = productBrowse(*(ProductBrowseParams *)msg.inputArgs); +// if (ret < 0) { +// m_event = e_event_commerceError; +// m_errorCode = ret; +// } +// _TOOLKIT_NP_DEL (ProductBrowseParams *)msg.inputArgs; +// break; +// } +// +// case e_message_commerceUpgradeTrial: +// { +// ret = upgradeTrial(); +// if (ret < 0) { +// m_event = e_event_commerceError; +// m_errorCode = ret; +// } +// break; +// } +// +// case e_message_commerceRedeemVoucher: +// { +// ret = voucherCodeInput(*(VoucherInputParams *)msg.inputArgs); +// if (ret < 0) { +// m_event = e_event_commerceError; +// m_errorCode = ret; +// } +// _TOOLKIT_NP_DEL (VoucherInputParams *)msg.inputArgs; +// break; +// } +// +// case e_message_commerceGetEntitlementList: +// { +// Job > tmpJob(static_cast > *>(msg.output)); +// +// int state = 0; +// int ret = sceNpManagerGetStatus(&state); +// +// // We don't want to process this if we are offline +// if (ret < 0 || state != SCE_NP_MANAGER_STATUS_ONLINE) { +// m_event = e_event_commerceError; +// reply.returnCode = SCE_TOOLKIT_NP_OFFLINE; +// tmpJob.setError(SCE_TOOLKIT_NP_OFFLINE); +// } else { +// getEntitlementList(&tmpJob); +// } +// break; +// } +// +// case e_message_commerceConsumeEntitlement: +// { +// int state = 0; +// int ret = sceNpManagerGetStatus(&state); +// +// // We don't want to process this if we are offline +// if (ret < 0 || state != SCE_NP_MANAGER_STATUS_ONLINE) { +// m_event = e_event_commerceError; +// reply.returnCode = SCE_TOOLKIT_NP_OFFLINE; +// } else { +// +// ret = consumeEntitlement(*(EntitlementToConsume *)msg.inputArgs); +// if (ret < 0) { +// m_event = e_event_commerceError; +// m_errorCode = ret; +// } else { +// m_event = e_event_commerceConsumedEntitlement; +// } +// } +// _TOOLKIT_NP_DEL (EntitlementToConsume *)msg.inputArgs; +// +// break; +// } +// + case e_message_commerceCheckout: + { + ret = checkout(m_checkoutInputParams); + if (ret < 0) { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + + case e_message_commerceDownloadList: + { + ret = downloadList(m_downloadInputParams); + if (ret < 0) { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + + case e_message_commerceCheckout_Game: + { + ret = checkout_game(m_checkoutInputParams); + if (ret < 0) { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + + case e_message_commerceDownloadList_Game: + { + ret = downloadList_game(m_downloadInputParams); + if (ret < 0) { + m_event = e_event_commerceError; + m_errorCode = ret; + } + break; + } + + case e_message_commerceEnd: + app.DebugPrintf("XXX - e_message_commerceEnd!\n"); + ret = commerceEnd(); + if (ret < 0) + { + m_event = e_event_commerceError; + m_errorCode = ret; + } + // 4J-PB - we don't seem to handle the error code here + else if(m_errorCode!=0) + { + m_event = e_event_commerceError; + } + break; + + default: + break; + } + + LeaveCriticalSection(&m_queueLock); +} + + +void SonyCommerce_Orbis::processEvent() +{ + int ret = 0; + + switch (m_event) + { + case e_event_none: + break; + case e_event_commerceSessionCreated: + app.DebugPrintf(4,"Commerce Session Created.\n"); + runCallback(); + break; + case e_event_commerceSessionAborted: + app.DebugPrintf(4,"Commerce Session aborted.\n"); + runCallback(); + break; + case e_event_commerceGotProductList: + app.DebugPrintf(4,"Got product list.\n"); + runCallback(); + break; + case e_event_commerceGotCategoryInfo: + app.DebugPrintf(4,"Got category info\n"); + runCallback(); + break; + case e_event_commerceGotDetailedProductInfo: + app.DebugPrintf(4,"Got detailed product info.\n"); + runCallback(); + break; + case e_event_commerceAddedDetailedProductInfo: + app.DebugPrintf(4,"Added detailed product info.\n"); + runCallback(); + break; + case e_event_commerceProductBrowseStarted: + break; + case e_event_commerceProductBrowseSuccess: + break; + case e_event_commerceProductBrowseAborted: + break; + case e_event_commerceProductBrowseFinished: + app.DebugPrintf(4,"e_event_commerceProductBrowseFinished succeeded: 0x%x\n", m_errorCode); + + if(m_callbackFunc!=NULL) + { + runCallback(); + } + + //assert(0); +// ret = sys_memory_container_destroy(s_memContainer); +// if (ret < 0) { +// printf("Failed to destroy memory container"); +// } +// s_memContainer = SYS_MEMORY_CONTAINER_ID_INVALID; + break; + case e_event_commerceVoucherInputStarted: + break; + case e_event_commerceVoucherInputSuccess: + break; + case e_event_commerceVoucherInputAborted: + break; + case e_event_commerceVoucherInputFinished: + assert(0); +// ret = sys_memory_container_destroy(s_memContainer); +// if (ret < 0) { +// printf("Failed to destroy memory container"); +// } +// s_memContainer = SYS_MEMORY_CONTAINER_ID_INVALID; + break; + case e_event_commerceGotEntitlementList: + break; + case e_event_commerceConsumedEntitlement: + break; + case e_event_commerceCheckoutStarted: + app.DebugPrintf(4,"Checkout Started\n"); + break; + case e_event_commerceCheckoutSuccess: + app.DebugPrintf(4,"Checkout succeeded: 0x%x\n", m_errorCode); + // clear the DLC installed and check again + app.ClearDLCInstalled(); + ui.HandleDLCInstalled(0); + break; + case e_event_commerceCheckoutAborted: + app.DebugPrintf(4,"Checkout aborted: 0x%x\n", m_errorCode); + break; + case e_event_commerceCheckoutFinished: + app.DebugPrintf(4,"Checkout Finished: 0x%x\n", m_errorCode); + if (ret < 0) { + app.DebugPrintf(4,"Failed to destroy memory container"); + } + + // 4J-PB - if there's been an error - like dlc already purchased, the runcallback has already happened, and will crash this time + if(m_callbackFunc!=NULL) + { + runCallback(); + } + break; + case e_event_commerceDownloadListStarted: + app.DebugPrintf(4,"Download List Started\n"); + break; + case e_event_commerceDownloadListSuccess: + app.DebugPrintf(4,"Download succeeded: 0x%x\n", m_errorCode); + break; + case e_event_commerceDownloadListFinished: + app.DebugPrintf(4,"Download Finished: 0x%x\n", m_errorCode); + if (ret < 0) { + app.DebugPrintf(4,"Failed to destroy memory container"); + } + + // 4J-PB - if there's been an error - like dlc already purchased, the runcallback has already happened, and will crash this time + if(m_callbackFunc!=NULL) + { + runCallback(); + } + break; + case e_event_commerceError: + app.DebugPrintf(4,"Commerce Error 0x%x\n", m_errorCode); + runCallback(); + break; + default: + break; + } + m_event = e_event_none; +} + + +int SonyCommerce_Orbis::commerceEnd() +{ + int ret = 0; + +// if (m_currentPhase == e_phase_voucherRedeemPhase) +// ret = sceNpCommerce2DoProductCodeFinishAsync(m_contextId); +// else if (m_currentPhase == e_phase_productBrowsePhase) +// ret = sceNpCommerce2DoProductBrowseFinishAsync(m_contextId); +// else if (m_currentPhase == e_phase_creatingSessionPhase) +// ret = sceNpCommerce2CreateSessionFinish(m_contextId, &m_sessionInfo); +// else if (m_currentPhase == e_phase_checkoutPhase) +// ret = sceNpCommerce2DoCheckoutFinishAsync(m_contextId); +// else if (m_currentPhase == e_phase_downloadListPhase) +// ret = sceNpCommerce2DoDlListFinishAsync(m_contextId); + + m_currentPhase = e_phase_idle; + + return ret; +} + +void SonyCommerce_Orbis::CreateSession( CallbackFunc cb, LPVOID lpParam ) +{ + // 4J-PB - reset any previous error code + // I had this happen when I was offline on Vita, and accepted the PSN sign-in + // the m_errorCode was picked up in the message queue after the commerce init call + if(m_errorCode!=0) + { + app.DebugPrintf("m_errorCode was set!\n"); + m_errorCode=0; + } + Init(); + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + + // We don't need to create a session on PS4, from the Sony docs - +// This function is provided to maintain compatibility with the PlayStationŽVita and PlayStationŽ3 +// platforms. Because commerce on the PlayStationŽ4 is not session based, SCE_TOOLKIT_NP_SUCCESS is always returned. + + + +// m_messageQueue.push(e_message_commerceCreateSession); + m_messageQueue.push(e_message_commerceEnd); + m_event = e_event_commerceSessionCreated; + + if(m_tickThread == NULL) + m_tickThread = new C4JThread(TickLoop, NULL, "SonyCommerce_Orbis tick"); + if(m_tickThread->isRunning() == false) + { + m_currentPhase = e_phase_idle; + m_tickThread->Run(); + } + LeaveCriticalSection(&m_queueLock); +} + +void SonyCommerce_Orbis::CloseSession() +{ + assert(m_currentPhase == e_phase_idle); + m_currentPhase = e_phase_stopped; + // 4J-PB - don't call shutdown here - the SonyCommerce_Orbis::TickLoop thread is still running and could crash accessing the critical section that Shutdown destroys + //Shutdown(); +} + +void SonyCommerce_Orbis::GetProductList( CallbackFunc cb, LPVOID lpParam, std::vector* productList, const char *categoryId) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_pProductInfoList = productList; + strcpy(m_pCategoryID,categoryId); + m_messageQueue.push(e_message_commerceGetProductList); + LeaveCriticalSection(&m_queueLock); +} + +void SonyCommerce_Orbis::GetDetailedProductInfo( CallbackFunc cb, LPVOID lpParam, ProductInfoDetailed* productInfo, const char *productId, const char *categoryId ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_pProductInfoDetailed = productInfo; + m_pProductID = productId; + strcpy(m_pCategoryID,categoryId); + m_messageQueue.push(e_message_commerceGetDetailedProductInfo); + LeaveCriticalSection(&m_queueLock); +} + +// 4J-PB - fill out the long description and the price for the product +void SonyCommerce_Orbis::AddDetailedProductInfo( CallbackFunc cb, LPVOID lpParam, ProductInfo* productInfo, const char *productId, const char *categoryId ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_pProductInfo = productInfo; + m_pProductID = productId; + strcpy(m_pCategoryID,categoryId); + m_messageQueue.push(e_message_commerceAddDetailedProductInfo); + LeaveCriticalSection(&m_queueLock); +} +void SonyCommerce_Orbis::GetCategoryInfo( CallbackFunc cb, LPVOID lpParam, CategoryInfo *info, const char *categoryId ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_pCategoryInfo = info; + strcpy(m_pCategoryID,categoryId); + m_messageQueue.push(e_message_commerceGetCategoryInfo); + LeaveCriticalSection(&m_queueLock); +} + +void SonyCommerce_Orbis::Checkout( CallbackFunc cb, LPVOID lpParam, const char* skuID ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_checkoutInputParams.skuIds.clear(); + m_checkoutInputParams.skuIds.push_back(skuID); + m_messageQueue.push(e_message_commerceCheckout); + LeaveCriticalSection(&m_queueLock); +} + +void SonyCommerce_Orbis::DownloadAlreadyPurchased( CallbackFunc cb, LPVOID lpParam, const char* skuID ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_downloadInputParams.skuIds.clear(); + m_downloadInputParams.skuIds.push_back(skuID); + m_messageQueue.push(e_message_commerceDownloadList); + LeaveCriticalSection(&m_queueLock); +} + +void SonyCommerce_Orbis::Checkout_Game( CallbackFunc cb, LPVOID lpParam, const char* skuID ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_checkoutInputParams.skuIds.clear(); + m_checkoutInputParams.skuIds.push_back(skuID); + m_messageQueue.push(e_message_commerceCheckout_Game); + LeaveCriticalSection(&m_queueLock); +} +void SonyCommerce_Orbis::DownloadAlreadyPurchased_Game( CallbackFunc cb, LPVOID lpParam, const char* skuID ) +{ + EnterCriticalSection(&m_queueLock); + setCallback(cb,lpParam); + m_downloadInputParams.skuIds.clear(); + m_downloadInputParams.skuIds.push_back(skuID); + m_messageQueue.push(e_message_commerceDownloadList_Game); + LeaveCriticalSection(&m_queueLock); +} + + +/* +bool g_bDoCommerceCreateSession = false; +bool g_bDoCommerceGetProductList = false; +bool g_bDoCommerceGetCategoryInfo = false; +bool g_bDoCommerceGetProductInfoDetailed = false; +bool g_bDoCommerceCheckout = false; +bool g_bDoCommerceCloseSession = false; +const char* g_category = "EP4433-CUSA00265_00"; +const char* g_skuID = "SKINPACK00000001-E001"; +std::vector g_productInfo; +SonyCommerce::CategoryInfo g_categoryInfo2; +SonyCommerce::ProductInfoDetailed g_productInfoDetailed; + +void testCallback(LPVOID lpParam, int error_code) +{ + app.DebugPrintf("Callback hit, error 0x%08x\n", error_code); +} + +void SonyCommerce_Orbis::Test() +{ + int err = SCE_OK; + if(g_bDoCommerceCreateSession) + { + CreateSession(testCallback, this); + g_bDoCommerceCreateSession = false; + } + if(g_bDoCommerceGetProductList) + { + GetProductList(testCallback, this, &g_productInfo, g_category); + g_bDoCommerceGetProductList = false; + } + + if(g_bDoCommerceGetCategoryInfo) + { + GetCategoryInfo(testCallback, this, &g_categoryInfo2, g_category); + g_bDoCommerceGetCategoryInfo = false; + } + + if(g_bDoCommerceGetProductInfoDetailed) + { + GetDetailedProductInfo(testCallback, this, &g_productInfoDetailed, g_productInfo[0].productId, g_category); + g_bDoCommerceGetProductInfoDetailed = false; + } + + if(g_bDoCommerceCheckout) + { + //Checkout(testCallback, this, g_skuID);//g_productInfoDetailed.skuId); + Checkout(testCallback, this, g_productInfoDetailed.skuId); + g_bDoCommerceCheckout = false; + } + if(g_bDoCommerceCloseSession) + { + CloseSession(); + g_bDoCommerceCloseSession = false; + } + +} +*/ \ No newline at end of file -- cgit v1.2.3